Monday, July 24, 2006

Edit and Compile Flex Apps in Dreamweaver

In what I think is a brilliant move by Adobe, the Flex 2 SDK and Flex 2 Framework are available for FREE. This is nothing new, but it's worth restating (it seems that a lot of people don't know it yet). I intend to make take full advantage of that fact until such time as I can afford Flex Builder. That's not to say that Flex Builder is unaffordable: quite the contrary. However, I also have to have licenses for Flash, Dreamweaver, Photoshop, and Illustrator. So for me, an extra $500 is substantial.

I actually see not having access to Flex Builder as an opportunity to learn. Like many, I learned HTML by hand-coding in Notepad, and it made me REALLY learn HTML. I think that not using Flex Builder will force me to learn the behind-the-scenes stuff, and therefore will end up being a positive thing. When I do buy the Builder license, I'll have a strong understanding of what's going on under the hood, as well as the conveniences of the Design view and robust code hinting.

Configuring Dreamweaver

Since I already have Dreamweaver, I'll use that as my XML editor. It's really easy to associate MXML files with Dreamweaver, and with a little configuration, you can take advantage of Dreamweaver's XML syntax highlighting. Here's how to do it in Windows:




1) Download the Flex 2 SDK from http://www.adobe.com/products/flex (the link is at the bottom of the page). Install the SDK by unzipping it to the directory of your choice. I put mine in the root of my C drive.

2) Associate MXML files with Dreamweaver. To do so, right-click a file with a .mxml extension, and click Properties. In the Properties dialog, find where it says "Opens with:" and click the "Change" button. Select "Dreamweaver" from the resulting menu. If you don't have any .mxml files yet, you can find one in C:\flex_2_sdk\Samples.

3) Enable XML syntax highlighting for .mxml files. For this, you need to edit one of Dreamweaver's configuration files. The specific file is called MMDocumentTypes.xml, and is located at C:\Program Files\Macromedia\Dreamweaver 8\Configuration\DocumentTypes. You can edit this with Dreamweaver. Find the tag and add "mxml" to the list of extensions in the "winfileextension" parameter. Save the file, and restart Dreamweaver.


At this point, you should be able to double-click an MXML file and have it open in Dreamweaver, complete with syntax highlighting. Now that's all well and good, but how do we compile it? The command-line compiler that comes with the SDK is fine, but typing commands over and over again when I want to build is not my idea of a good time. Wouldn't it be swell if you could compile from Dreamweaver?

Creating a Command to Compile MXML

Yup! Thanks to Dreamweaver's robust extensibility API, it's pretty easy to write a command that will compile the active MXML document and launch the resulting SWF in the stand-alone player. Here's how it's done:

1) Create a new JS file and put the following code in it:

// Compile mxml file from Dreamweaver

function flexCompile(){

var currentDocURL = dreamweaver.getDocumentPath("document");
var i = currentDocURL.lastIndexOf("/");

var parentDirectoryURL = currentDocURL.substring(0,i+1);
var fileNameURL = currentDocURL.substring(0,currentDocURL.lastIndexOf("."));

var parentDirectory = MMNotes.localURLToFilePath(parentDirectoryURL);
var fileName = MMNotes.localURLToFilePath(fileNameURL);

var currentDocFile = MMNotes.localURLToFilePath(currentDocURL);
if(!currentDocFile){
alert("You must have an mxml document open to compile.");
}else{
MM.createProcess('', 'C:\\flex_sdk_2\\bin\\mxmlc.exe "'+currentDocFile+'" -output "'+fileName+'.swf"', -1, true, parentDirectory ,parentDirectory+'flex-compiler-output.txt');
dreamweaver.openWithApp(fileNameURL+'.swf','file:///C:/flex_sdk_2/player/debug/SAFlashPlayer.exe');
}
}

function canAcceptCommand(){
return dreamweaver.getDocumentPath("document").indexOf(".mxml") != -1;
}



2) Create a new HTML file, and put the following code in it:

<!DOCTYPE HTML SYSTEM "-//Macromedia//DWExtension layout-engine 5.0//
dialog">
<HTML>
<HEAD>
<Title>Flex Compile</Title>
<SCRIPT SRC="Flex Compile.js"></SCRIPT>

</HEAD>
<body onLoad="flexCompile()">
</body>
</HTML>

3) Save these to Dreamweaver's "Commands" folder (C:\Program Files\Macromedia\Dreamweaver 8\Configuration\Commands) as Flex Compile.js and Flex Compile.htm, respectively.


4) Restart Dreamweaver. You should now have a new item in the "Commands" menu called "Flex Compile" which will compile the active MXML document with the Flex 2 compiler, launch it in the standalone player, and save a text file of the compiler output.

How It Works

When you click the Flex Compile menu option, Flex Compile.htm is loaded, and its body.onload function is called, which is our flexCompile function. First, a few useful variables are set. We get the file path of the active document using dreamweaver.getDocumentPath("document"), which returns the location of the active document as a URL. Then we can get the URL of the parent directory by taking a substring of the currentDocURL - everything before and including the last "/" character. Now for these to be useful to us, we must convert them to file paths. To do this, we call MMNotes.localURLToFilePath(), which is part of the Design Notes API. This function changes the syntax of the file path from URL syntax ('file:///C:/directory/filename.xxx') to file path syntax ('C:\directory\filename.xxx') .

Next comes the real magic, an undocumented command called MM.createProcess(), which I found at http://www.communitymx.com/blog/index.cfm?newsid=179&blogger=35. This allows us to send a command to the compiler without opening it in a command-line window, and it can also be configured to make Dreamweaver wait while the compiling takes place. Note that in my command, I have hard-coded the path to the compiler. If you want to keep the Flex 2 SDK anywhere other than C:\flex_2_sdk, you will have to update the JS file. Also note that in MM.createProcess, the backslashes have to be escaped.

I have configured this command to put the SWF output in the same directory as the mxml file. MM.createProcess also optionally sends the output of the process to a text file, which I have opted for in this command. It will create a text file called 'flex-compiler-output.txt' in the same directory as your mxml file.

Next, I call dreamweaver.openWithApp to launch the SWF in the standalone player. Again, I have hard-coded the path to the Flex 2 SDK.

The function canAcceptCommand() simply ensures that the command is grayed out unless an MXML document is the active document in Dreamweaver.

Conclusion

I believe this setup has a great deal of potential as a basic Flex 2 workflow. One could easily imagine a more configurable version of the Flex Compile command where you could specify the path for the SWF output, or the path to the Flex 2 SDK. What I was going for with this command was to mimic the functionality of Preview in the Flash IDE, so that as I make edits to the MXML I can easily see the results of my changes. Ultimately, this makes up for the lack of a design view, which is one of the great benefits of Flex Builder.

Since I would prefer to work on my Mac, I am creating a Mac version of this command. It will probably have to rely on a shell script or AppleScript to achieve similar functionality since MM.createProcess (and its friends) do not work on the Mac. There is some promise with the undocumented dw.runAppleScript() command, but it does not appear to work on my MacTel.

On the XML-editing side of things, I will probably explore creating an MXML file template for Dreamweaver, as well as rudimentary code-completion. Thanks to Dreamweaver's robust extensibility, I will be able to efficiently create Flex applications without buying Builder, and learning a lot in the process.

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.

24 Comments:

Anonymous Anonymous said...

Excellent! This is one of the natural results of what Adobe did by making the SDk and compiler free. I expect to see many efforts like yours being released within the next year. I'd love to see what you can do for Dreamweaver for the Mac. Is the Flash IDE extensible in the same way?

6:39 AM  
Blogger tom said...

Yes, it is! Just Google 'JSFL' or check out 'Extending Flash' in Flash Help. There have been some awesome extensions made for Flash - to give you an idea what is possible, check out gProject.

6:56 AM  
Anonymous Anonymous said...

Thanks for this great tip !
Your command saved me a 1000 bucks ;)

10:18 AM  
Blogger tom said...

Update: I have added a workable solution for the Mac! Check it out here.

12:08 PM  
Anonymous Anonymous said...

I found your post searching "mxml dreamweaver 8" on Google. Thanks for figuring this out and sharing!

11:28 AM  
Anonymous Anonymous said...

Fantastic! Now all we need is for someone to generate code hinting for MXML in DW, and we're all set!

11:03 AM  
Anonymous Anonymous said...

This is nice. However, the MM.CreateProcess section of the Flex Compile.js file uses flex_sdk_2 vice flex_2_sdk so please be aware of this when deciding where to install your flex 2 sdk. When I worked through the instructions (which were well written) I got a compile error for the SAFlashPlayer.exe (file couldn't be found). Once I modified the Flex Compile.js file to point to the correct directory, the compiler worked perfectly. Now, if there was a way to use the flex components to visually design an application I'd be well on my way to taking advantage of Flex without the $750.00 price tag!!!

4:09 AM  
Blogger Unknown said...

Thanks for putting this together its a great! I have a problem though:
I tried using the MMDocumentTypes.xml but DeamWeaver pops up with a dialog saying the doc types "...will not be added because it uses a file extension that is already associated with a prior Document Type" (this is with alll of the doc types in this file I think). I even tried manually editing the file but its the same. It seems that even if you don't change anything within this file (Save as) it throws up the pop-ups.

2:44 AM  
Blogger Ariel said...

Thank you very much. I appreciate this blog entry.

11:56 PM  
Anonymous Anonymous said...

This is a kick ass solution...


Thanks

4:23 PM  
Anonymous Anonymous said...

These comments have been invaluable to me as is this whole site. I thank you for your comment.

11:51 AM  
Blogger Vijay said...

Hi,

This does not work, i tried all the steps, but I get an error saying Flex Compile is not defined....

5:41 AM  
Blogger tom said...

At what point do you get the error? When you click the Flex Compile menu item?

7:31 AM  
Blogger Leblanc and Janie Wedding said...

since adobe is creating plug-ins for eclipse will dreamweaver be discontinued in the near future?

9:36 PM  
Anonymous Anonymous said...

Finally found really useful information on the topic, thank you.

If interested, can visit Pennsylvania Home Owner Insurance - Interesting fact blog.

1:34 PM  
Anonymous Anonymous said...

Hi. Sounds great in theory, but for some reason Flash Player just comes up with a blank page, though the mxml has been compiled and i can open the resulting swf manually - any ideas?

here's my modified Flex Compile.js:

// Compile mxml file from Dreamweaver

function flexCompile(){

var currentDocURL = dreamweaver.getDocumentPath("document");
var i = currentDocURL.lastIndexOf("/");

var parentDirectoryURL = currentDocURL.substring(0,i+1);
var fileNameURL = currentDocURL.substring(0,currentDocURL.lastIndexOf("."));

var parentDirectory = MMNotes.localURLToFilePath(parentDirectoryURL);
var fileName = MMNotes.localURLToFilePath(fileNameURL);

var currentDocFile = MMNotes.localURLToFilePath(currentDocURL);
if(!currentDocFile){
alert("You must have an mxml document open to compile.");
}else{
MM.createProcess('', 'C:\\Program Files\\Adobe\\Flex Builder 2\\Flex SDK 2\\bin\\mxmlc.exe "'+currentDocFile+'" -output "'+fileName+'.swf"', -1, true, parentDirectory ,parentDirectory+'flex-compiler-output.txt');
dreamweaver.openWithApp(fileNameURL+'.swf','file:///C:/Program Files/Adobe/Flex Builder 2/player/debug/SAFlashPlayer.exe');
}
}

function canAcceptCommand(){
return dreamweaver.getDocumentPath("document").indexOf(".mxml") != -1;
}

is there a problem here 'cos my Flash player isn't at the same path as the Flex SDK? i presume not as it launches the player but doesn't open the swf, hence my confusion

any help greatly appreciated

thanks,

Gareth

5:43 AM  
Blogger Vijay said...

Hi,

I use Dreamweaver MX 2004 and I have Flex 2.0 SDK installed. I followed your blog entry, If I double click, the MXML opens DM2004 but it doesn't open the file - I get a message saying "Failed to Open Document". But when I force it to open using File Open, it opens up with syntax highlighting.

What is the problem ?, also the Flex Complie option doesn't work, I believe it could be as you had hardcoded the Flex Complier ??

Please attend to this problem...many thanks for bringing up this excellent post.

2:09 AM  
Anonymous Anonymous said...

My question is, do you think Adobe will continue with Flex? I'm uncertain - so i'm worried about throwing myself any deeper into it.

11:53 AM  
Anonymous Anonymous said...

wrought iron garden gates,
your nest iron garden gates, here,

2:53 PM  
Blogger Nadhilah said...

Hi,

I use Dreamweaver MX 2004 and I have Flex 2.0 SDK installed. I followed your blog entry, If I double click, the MXML doesn't open the file. I must using the open with but - I get a message saying "Failed to Open Document". But when I force it to open using File Open, it opens up with syntax highlighting.

What is the problem ? also the flex compile cannot compile it.

3:41 AM  
Anonymous Anonymous said...

This comment has been removed by the author.

8:09 AM  
Blogger Unknown said...

This comment has been removed by the author.

9:17 AM  
Blogger bollywood girls said...

i like your blog ....

10:18 PM  
Anonymous Anonymous said...

Thanks u r information

10:18 PM  

Post a Comment

<< Home