Roger Braunstein

Introduction to Flex Resource Bundles

Hark, Flex developers. Lend me your ears! I must take this post to implore you: use Resource Bundles! Trust me, I know, there’s a lot to keep up with these days, but if you aren’t already privy to the awesome secrets of the humble bundle, hopefully I can help convince you to use them. I’ll show you how, without breaking one bead of sweat from your brow! First, let me tell you why they’re cool. Then, I’ll show you how to get rolling with your first bundle. Then, I’ll set you loose, and hopefully you can all write in with excellent questions and help me make this a great resource for the next readers! Read on, fair Flexer.

Why Bundles Will Give You a New Brain

This is from Upright Citizens Brigade. I don't advocate getting really high every day or doing your dishes in the bathtub.

Eight years ago, I weighed 500lbs. I was getting really high every day. And I was washing my dishes in the bathtub. But thanks to resource bundles, I own a mansion, I’ve got a summer home in Maine, I got an awesome boat, I got a jet pack, and I got a sweet lookin’ wife.

What’s a resource bundle? It’s a set of values that you externalize from your source code in a properties file. And it can be swapped out at compile time or, with Flex 3, at runtime. Think of it like a style sheet for values. Most of the time, these values are text. But without too much hassle, you can use resource bundles to parameterize all types of data.

Resource bundles are probably most useful, and most commonly used for, localization. Localization (pardon the didacticism) is the process of making software comprehensible for multiple regions with different languages or ways of writing. Sometimes you’ll see this term written L10n. For example, in porting your “Hello, world” application for a Japanese audience, you’d probably make it say something like “今日は、世界” instead. Resource bundles are perfect for supporting multiple locales.

This obvious use case, I’m afraid, might have prevented many of you from looking into resource bundles. If resource bundles are for localization, and you’re building a site that doesn’t need to be localized, you might well overlook their benefits, as I did for some time. However, here’s some of the benefits of using resource bundles — even if it’s just one single bundle.

Using resource bundles, you can give every application you write a copy deck. If you’ve worked with almost any client ever, I’m sure you’ve had to make a copy change. Who wants to go digging through source code to find that string? Put all your application’s copy in a resource bundle, and you can not only make these changes with ease, you can deliver source code that anyone can modify easily. (Copy decks are a necessity when using translation services as well.)

You can use resource bundles to store configuration values such as paths, numbers, Boolean flags, debug mode, overrides, etc. You can use a resource bundle instead of a configuration file or static constants.

You can even use resource bundles to reskin applications. Flex lets you parameterize embedded images in resource bundles. Alternately, if you load images at runtime, you can parameterize those URLs in a resource bundle. So, if your code references resources instead of direct embeds, you can change the look of your app by swapping out the bundle with all the image embeds!

Even if you don’t use resource bundles for any sort of behavior, language, or appearance toggling in your application, bundles are a fantastic way to separate code and content and organize related sets of content.

In brief, resource bundles will make your life easier, your program modular, and your project structure tidy!

What a World With Resource Bundles Looks Like

Pretty soon I’ll show you the specifics of how to set up your project to use resource bundles. But before we get into technicalities, let me describe a few formats. There’s a few ways you can use resources, and there’s the property file format to cover as well.

Ok, again pardon the ultimately pedantic example, but let’s say you have a hello world app.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
	<mx:Label text="Hello, world!"/>
</mx:Application>

You clearly wrote this application for an English-speaking audience. And that bias exists in your code. It’s completely tied to your source file! Shame. If you wanted to write a Spanish version, you’d have to go right in and edit your source code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
	<mx:Label text="¡Hola, mundo!"/>
</mx:Application>

But, with resource bundles, this is what the one, true, final and never-changing source code could look like:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
	<mx:Label text="@Resource(key='message', bundle='copydeck')"/>
</mx:Application>

That’s one way, and indeed my favored way, of accessing resources from a resource bundle. This is going to look for the key message inside the bundle called copydeck.properties, and place its value in the text attribute of this Label instance, thus setting the text. Right now it looks like a lot more to type, but trust me, once you have a site or app with hundreds of lines of text, you are really going to appreciate how this makes your code concise and puts the text all together where it should be!

Note that you can use this @Resource directive in MXML in more places than just text attributes. You could use it to set tooltips, style properties, sizes, all kinds of things!

So let’s take a quick look at this outrageously simple properties file. This file format is really really easy.

#locale/en_US/copydeck.properties
message=Hello, world!
message-size=30
#locale/es_MX/copydeck.properties
message=¡Hola, mundo!
message-size=40

Here we see two copies of the properties file, made for two locales (American English and Mexican Spanish — locales are not just specific to the language but the region as well, but that’s another story). There’s pretty much only three things to know about properties files.

  • Key = value. Do I need to explain this? Don’t sweat the whitespace.
  • Comments are whole lines that begin with #.
  • Properties are one line long unless you end the line with a backtick (\), in which case you can continue on the next line.

In reality, there are alternate formats for the first two rules, but only use that if you really have to be different. There’s something to be said for the naming convention of the bundles. The directory structure I’ll explain a bit later, but know that en_US and es_MX are locale codes, combining a language code and a country code. The name of the file before its .properties extension is going to yield the bundle name itself.

Now, you can skip the whole step of specifying the bundle name by having one properties file per class file, and naming the properties file in parallel with the name of the class using it. If you do this, you can omit the bundle='whatever' attribute of the @Resource directive, but I advise against this. I advocate that you split up your resource bundles by purpose. For example, one recent project I worked on uses a bundle for copy and a bundle for skinning. Another recent project uses one bundle for copy and another for stylesheets.

So I hear you, you’re one of those hardcore doods who uses Flex but prefers to code in AS3. That’s cool, I’m down with that. Or maybe you just have something more interesting to do with those values coming out of resource bundles (configuration variables perhaps). There’s some nice ways of accessing values from resource bundles in code. Maybe looking at this will get you started:

package
{
	import mx.containers.Canvas;
	import mx.controls.Label;

	[ResourceBundle("copydeck")]
	public class View extends Canvas
	{
		public function View()
		{
			super();
			var label:Label = new Label();
			label.text = resourceManager.getString("copydeck", "message");
			label.setStyle("fontSize", resourceManager.getNumber("copydeck", "message-size"));
			addChild(label);
		}
	}
}

If you’re in a class that doesn’t have its own reference to the ResourceManager, like Canvas here does, you can equally well use ResourceManager.getInstance(). Further, there are lots of other cool typed accessor methods you can use. Keep in mind that any bundles you reference in AS3 only must be explicitly included by using [ResourceBundle] metadata tags.

For more information about intermediate techniques like embedding assets and loading/swapping resource bundles at runtime, check out the very good section on localization in the Livedocs.

The Petty Particulars of Putting it to Practice

Now, I’m not going to leave you hanging with just some code examples. There’s a few things you need to know about structuring your Flex projects to take advantage of resource bundles. It’s really not that complicated, though, so not to worry!

First, you should pick a place for your resource bundles to live. Even if I’m only ever making apps for my United States English locale, I still like to make a locale/en_US folder, and place all my properties files inside there. I recommend you do the same.

Now here’s one tricky point. This directory must be one of the source directories in your Flex project. The compiler has to be able to crawl to those properties files, and it stays away from any place you haven’t specified in your build path. Again, even if I only have one locale ever, I like to keep this parameterized. Assuming you used the directory structure above, step one is to add the following directory to your build path:

locale/{locale}

The play-by-play, if you need it: right-click your project, choose Properties. Choose ActionScript Build Path on the left column, choose the Source Path tab, click Add Folder… and enter locale/{locale}.

screenshot

Finally, Flex Builder is going to get this locale variable from somewhere, and that’s from the arguments sent to mxmlc. Simply add the option

-locale=en_US

to your compiler arguments, or of course, substitute the locale in use. This value will replace the {locale} variable in the source path, and switch mxmlc to use the copies of the properties files in the correct location for the locale (or skin, or whatever…).

Again, the play-by-play. Right click your project, choose Properties. Choose ActionScript Compiler on the left column, and add the option just mentioned to any others that your project requires (if any).

screenshot

Conclusion

That’s all it should take to get you started with resource bundles! I hope that I’ve convinced you that resource bundles are a fun, safe, and effective way to separate your code and your content, whether your application will be localized and skinned or not! Separate your copy from your code. The next person to touch your code will thank you. If you use MXML with external CSS files and external resource bundles, you might achieve some sort of ultimate code separation enlightenment.

Did I miss anything? Run into any problems? Leave me a comment!

8 Responses to “Introduction to Flex Resource Bundles”

  1. shaun Says:

    Nice article. Thanks.

  2. tripleaxis Says:

    Great that someone’s put up an article about bundles.
    When I first saw it in the feature list, I mentally ticked it for a review at a later date, but kinda never did.

    *rolls up sleeves and thumbs jet-pack catalogue*

  3. 36 New, Cool Flex and AS3 Tools, Libraries and Components Says:

    [...] Flex Resource Bundles What’s a resource bundle? It’s a set of values that you externalize from your source code in a properties file. And it can be swapped out at compile time or, with Flex 3, at runtime. Think of it like a style sheet for values. http://blog.extends.eventdispatcher.org/roger/introduction-to-flex-resource-bundles/ [...]

  4. Roms Says:

    Thanks for this, it’s really interesting and you make it easy to understand :)

  5. Eric Says:

    Hi Roger,

    Great article, i was wondering however if its possible to load the properties file from an external source during runtime. I need to be able to change the properties file without recompiling the entire code and redeploying. Thanks in advance

    /Eric

  6. David Says:

    Hi Roger, great article!

    What about the comment of Eric… I was wondering the same thing.
    Resource bundles are a great, easy and fast way to modify your app without crawling through your code. But you still have to recompile it..

    Two years ago, probably was with Flex 1.5, i had to develop an easy app that should have 3 different versions, depending on language and another variable, some text, colors and images should change.
    I opted for an xml configuration file that was loaded after reading a FlashVars in html.. So if the client wants to have a text or image change, i, or even himself, can just easily update the xml on the server and that’s it.

    What are the backdraws of this solution and what do you suggest since Flex has changed a lot during the past two years…
    bye

  7. James Rowley Says:

    Hi - i need to use resource bundles with Flash, not Flex. Would this work well in AS3 too - or does it require the power of Flex ? If it does - do u have any examples in AS3 only?

  8. Roger Braunstein Says:

    @James,

    Resource bundles work with Flex and use its built-in managers. You would be hard-pressed to excise this part of the framework and selectively make this work in an AS3-only project, though I’m sure it’s technically possible.

    I know what you are after, though - I want the same flexibility. These days in my AS3-only projects, I will always have a copy deck XML file and CopyDeck singleton class. I use the following techniques to make this copy stupid-easy to include in my projects:

    Automatic Model Binding
    and occasionally, when I don’t want to load the copy deck at runtime,
    Arbitrary Data Embedding

    This makes things pretty easy.

Leave a Reply