SWFAddress is not only a great deep linking solution with applications created in Flash, it also works incredibly well for deep linking in Flex. It’s an excellent solution because along with easily implementing in an application, you can use SWFAddress to display any state of an application when it initializes. This section demonstrates how to use SWFAddress in a Flex application.
This excerpt is from Search Engine Optimization for Flash. Search Engine Optimization for Flash dispels the myth that Flash-based websites won't show up in a web search by demonstrating exactly what you can do to make your site fully searchable -- no matter how much Flash it contains. You'll learn best practices for using HTML, CSS and JavaScript, as well as SWFObject, for building sites with Flash that will stand tall in search rankings.
You begin with a few small steps when implementing SWFAddress in
a Flex app. First, you need to have the right files in the right
places. The SWFAddress.as and
SWFAddressEvent.as files need to be
in the src folder for your
application, and the JavaScript folder swfaddress containing swfaddress.js needs to be in your output folder,
bin-debug. You can create a Flex
project using the SWFAddress folder
as your main folder, and by setting App.mxml as your main application file.
After the files are in the appropriate places, you can write the
code for your application to implement SWFAddress. Start by making
sure your output HTML file links to swfaddress.js using the following code:
<script type="text/javascript" src="swfaddress/swfaddress.js"></script>
Your HTML code should also be using SWFObject, which was discussed earlier in this chapter. Next, you’re ready to write the MXML code. Here’s an example of code that utilizes SWFAddress:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="initApp()">
<mx:Script>
<![CDATA[
import mx.containers.VBox;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import mx.controls.Text;
import SWFAddress;
private var req:URLRequest = new URLRequest("data.xml");
private var loader:URLLoader = new URLLoader();
private var xmlData:XML;
private var urls:Array = new Array();
private function initApp():void
{
loader.addEventListener(Event.COMPLETE,loadComplete);
loader.load(req);
SWFAddress.onChange = handleSWFAddress;
}
private function loadComplete(event:Event):void
{
xmlData = new XML(loader.data);
for each(var game:XML in xmlData.game)
{
var vbox:VBox = new VBox();
var field:Text = new Text();
field.text = game.description;
vbox.label = game.title;
navigator.addChild(vbox);
vbox.addChild(field);
field.width = 375;
field.height = 100;
urls.push(formatAsURL(game.title));
}
}
private function handleSWFAddress():void
{
var value:String = SWFAddress.getValue();
value = value.replace(/\//g, "");
navigator.selectedIndex = urls.indexOf(value);
SWFAddress.setTitle(formatAsTitle(value));
}
private function setSWFAddress():void
{
SWFAddress.setValue("/" + urls[navigator.selectedIndex] + "/");
}
private function formatAsURL(t:String):String
{
var formatted:String = t;
return formatted.replace(/ /g,"-");
}
private function formatAsTitle(t:String):String
{
var formatted:String = t;
return formatted.replace(/-/g," ");
}
]]>
</mx:Script>
<mx:TabNavigator id="navigator" width="400" height="150"
change="setSWFAddress()">
</mx:TabNavigator>
</mx:Application>
Now walk through how this application works. Much of the app is
the same application you looked at earlier in this chapter. For
example, in the <mx:Application>
tag, the creationComplete event is set
to trigger initApp(), which initiated
the loading of the XML file. Here’s the <mx:Application> tag:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()">
And here’s the initApp()
function:
private function initApp():void
{
loader.addEventListener(Event.COMPLETE,loadComplete);
loader.load(req);
SWFAddress.onChange = handleSWFAddress;
}
Notice the initApp() function has
only one new line of code:
SWFAddress.onChange = handleSWFAddress;
This line of code runs the handleSWFAddress() function whenever the
SWFAddressEvent.CHANGE event occurs.
This way is a shorthand way of using addEventListener() to connect an event handler
function to an event. You’ll look at what handleSWFAddress() does later in this section.
The application has one new variable, urls:
private var urls:Array = new Array();
This variable holds the URL formatted versions of all URLs, as
stated in the bottom of the loop at the end of the loadComplete() function:
private function loadComplete(event:Event):void
{
xmlData = new XML(loader.data);
for each(var game:XML in xmlData.game)
{
var vbox:VBox = new VBox();
var field:Text = new Text();
field.text = game.description;
vbox.label = game.title;
navigator.addChild(vbox);
vbox.addChild(field);
field.width = 375;
field.height = 100;
urls.push(formatAsURL(game.title));
}
}
The URLs are formatted using the formatAsURL() function to format each game title.
The returned URL is then stored in the urls array. Here’s the formatAsURL() function:
private function formatAsURL(t:String):String
{
var formatted:String = t;
return formatted.replace(/ /g,"-");
}
This function simply holds a duplicate of the string passed in
within the formatted variable, and then uses the string’s
replace method to replace all spaces with hyphens. The code
/ /g is a Regular Expression—powerful string
referencing code, that identifies all spaces using the global
g operator.
Address changes for SWFAddress are initiated with the
TabNavigator’s change event, which triggers the setSWFAddress() function:
<mx:TabNavigator id="navigator" width="400" height="150" change= "setSWFAddress()">
Look at the setSWFAddress()
function:
private function setSWFAddress():void
{
SWFAddress.setValue("/" + urls[navigator.selectedIndex] + "/");
}
This function simply calls SWFAddress’ setValue() method to update the address in the
browser’s URL. The updated address is the URL formatted game
title that corresponds to the selectedIndex of the TabNavigator, wrapped in
forward slashes (/). SWFAddress also begins all updates to URLs
with a hash character (#).
SWFAddress’ setValue() method
triggers the SWFAddressEvent.CHANGE
event, which runs the handleSWFAddress() function. Here’s that
function:
private function handleSWFAddress():void
{
var value:String = SWFAddress.getValue();
value = value.replace(/\//g, "");
navigator.selectedIndex = urls.indexOf(value);
SWFAddress.setTitle(formatAsTitle(value));
}
The handleSWFAddress() function
begins by capturing SWFAddress’ value—the fragment
portion of the URL, using its getValue() method. Then, the forward slashes in
the value are stripped using the String.replace() method and a Regular Expression.
Next, the TabNavigator’s selectedIndex is set to whatever index corresponds
to the current value of SWFAddress,
which is retrieved using the urls
Array’s indexOf() method.
Finally, the title in the browser window is updated using
SWFAddress’ setTitle() method. The value passed in is the
value returned from the formatAsTitle() function.
Let’s look at formatAsTitle():
private function formatAsTitle(t:String):String
{
var formatted:String = t;
return formatted.replace(/-/g," ");
}
Where the formatAsURL() function
accepts a game title and returns a URL, this function does the
opposite. It accepts a game’s URL, and then returns its
title.
In order to work properly, the application should be tested using a testing server. When you do test this in a testing server, you see the URLs and page titles update when you click the different tabs (Figure 6.15, “Viewing SWFAddress working in a Flex application”). Further, if you attempt to initialize the application with a URL that contains a fragment, then the application initializes to show its correct state.
Copyright © 2009 O'Reilly Media, Inc.