Chapter 36. Creating Extensions




  •  Before Getting Started
  •  The Dreamweaver API
  •  Creating Object Extensions
  •  Creating Command Extensions
  •  Packaging Your Extensions
  •  Summary

You learned in the preceding chapter how to take advantage of Dreamweaver extensions written by other people. For ultimate power in Dreamweaver, it's also possible to write your own. This chapter discusses how Dreamweaver uses JavaScript, HTML, and XML to create extensions, and how you can create two of the most popular and accessible types of extensions objects and commands.

Before Getting Started

Although writing Dreamweaver extensions isn't just for propeller-heads, it isn't for sissies, either. To work with object and command files, you need to be fairly comfortable reading and writing HTML code; and you need some understanding of JavaScript. In particular, you should be familiar with the basic language structure, syntax requirements and concepts of JavaScript (expressions, variables, functions, and so on), and how to use JavaScript to process data collected by HTML forms.



If you're a JavaScript newbie, or your skills are rusty, you might want to have a JavaScript reference available as you work. The handiest reference is the JavaScript section in the Dreamweaver Reference panel (see Chapter 33, "Writing Code in Dreamweaver"). If you want more in-depth information, the O'Reilly series books on JavaScript (JavaScript in a Nutshell, JavaScript Pocket Reference) are a valuable resource.

Writing extensions is also an inherently dangerous occupation. Because you are messing around in the guts of Dreamweaver, you can very easily break the program. In Chapter 35, "Working with Extensions," you learned about the Configuration folder and its role in Dreamweaver functionality. Writing extensions involves altering the Configuration folder. Always make a backup of this folder before you begin exploring and tinkering. If disaster strikes and Dreamweaver stops functioning properly, just quit Dreamweaver, trash the corrupted Configuration folder, and replace it with your backup. The next time you launch the program, all should be well.

You'll also need a text editor to create all the code involved in extending Dreamweaver. Odd as it might sound, many extending tasks can be done using Dreamweaver itself as the text editor. It's not recommended, though. Editing some configuration files, like menus.xml or insertbar.xml, while Dreamweaver is running can cause problems. You can also get very confused trying to create code in Dreamweaver. You might, however, want to use Dreamweaver Design view to help you design the interfaces for your extensions.

The Dreamweaver API

Dreamweaver extensions are constructed following the Dreamweaver application programming interface (API), which consists of all the procedures, file construction specifications, custom functions and formatting instructions that determine how and when commands will be processed and dialog boxes will appear, and so on. Learning how to write your own extensions means getting familiar with the API. The official "dictionary" that explains and documents the API is Macromedia's Extending Dreamweaver manual. This manual comes in PDF format on the Dreamweaver application CD-ROM; you also can download the PDF from the Macromedia web site ( support/dreamweaver/).

How Extensions Are Constructed

Each extension (object, behavior, command, inspector, floating panel, report, translator, and so on) consists of one or more files in the Configuration folder. The file types are as follows:

  • HTML file. Each extension begins with an HTML file. For every command, every object, every behavior, there is one HTML file that is the extension. Form elements, placed in the body, become the user interface for the extension.



    Every time there's a rule, there's an exception. While most extensions exist in HTML and JS files, it is possible to create simple extensions that exist solely as command lines built into menus.xml. How that works is beyond the scope of this chapter.

  • JS file. Each extension gains its functionality through JavaScript. The script functions can be placed in the head of the main HTML file, or (more frequently) are found in JS files linked to the HTML file. Complex extensions might link to several JS files.

  • GIF files. Icons, buttons, and any other graphic elements that appear in the user interface are created from GIF images, which are also stored in the Configuration folder.

In addition to these files, each extension might have an entry in one of the XML files, such as menus.xml or insertbar.xml that Dreamweaver uses to populate many of its interface elements.

How Extensions Are Processed

For each extension type, the Dreamweaver API has a procedure that determines how the extension's JavaScript instructions will be processed. This procedure often involves custom JavaScript functions that Dreamweaver executes automatically at certain times (on startup, when the user clicks something, and so on).

How Extensions Talk to Dreamweaver

How does an extension tell Dreamweaver to open a new document, insert or edit document contents, or whatever else you want it to do? The API includes a variety of predefined JavaScript objects, each of which contains various methods (functions) that you use to communicate with different parts of the program. The main objects are as follows:

  • The Dreamweaver (dw) object. This object contains dozens of methods to control application-wide behavior. Some sample methods are dw.openDocument(), dw.browseForFileURL(), dw.openWithExternalEditor(), dw.undo(). This object also contains child objects representing different parts of the application, each of which has its own set of methods for instance,

    dw.cssStylePalette.editSelectedStyle(),  dw.historyPalette.startRecording(),  dw.timelineInspector.setCurrentFrame().


  • The Document (dom) object. This object contains hundreds of methods, controlling all aspects of document editing. Document object methods and properties can be used to manipulate the selection (dom.getSelectedNode(), dom.setSelection()); can change any document property (dom.body.bgcolor="000000"); and can access and edit any item in a document (dom.deleteTableRow()).

  • The Site object. This object contains methods for working with sites and the Site panel. Site methods enable you to get and put files (site.get(), site.put()); perform sitewide file-management chores (site.findLinkSource(), site.locateInSite()); and work with the Site panel itself (site.editColumns(), site.setFocus()).

In addition to these main objects, other custom JavaScript objects give access to specific areas of Dreamweaver, such as working with web servers (the MMHttp object), working with Flash and Fireworks (SWFFile, FWLaunch), Design Notes (MMNotes), and so on. All of these objects, methods, and properties are detailed in the Extending Dreamweaver manual, mentioned earlier.

Creating Object Extensions

The simplest kind of Dreamweaver extension to understand and create is the object. An object, in terms of the Dreamweaver API, is an HTML file that contains, or uses JavaScript to construct, a string of HTML code to insert into the user's document. The user clicks an icon in the Insert bar, or selects an item from the Insert menu, and the specified code is inserted into the current document, usually at the insertion point.

Objects in the Configuration Folder

As you learned in the preceding chapter, object files are stored in subfolders of the Configuration/Objects folder that correspond to object categories in the Insert bar. Most objects consist of from one to three files, all with the same name but different extensions. These files are as follows:

  • An HTML file (table.htm, for instance). This is the object file itself. The file that contains or returns the code to be inserted. This is the only file that must be present to constitute an object.

  • A JavaScript file (table.js, for instance). This file contains JavaScript instructions for constructing the code to be inserted, in the form of one or more JavaScript functions, and is called on from the HTML file. This file is optional: It is entirely legal to contain the JavaScript functions in the head section of the object file instead of saving it to an external file. As experienced scripters know, it can be easier to keep track of and update JavaScripts if the code is in a separate file but it isn't necessary.

  • An image file (table.gif, for instance). This file contains an 18x18 pixel image that Dreamweaver uses to represent the object in the Insert bar. This file is also optional: If there is no image file, Dreamweaver will supply a generic image icon to represent the object in the panel.

Figure 36.1 shows some typical sets of object files.

Figure 36.1. Files for the Date object (two files only) and the Image object (three files), both found in the Configuration/Objects/Common folder.


Objects in the Insert Bar: insertbar.xml


Dreamweaver MX relies heavily on XML files to help construct a unified interface from its many files and extensions. The insertbar.xml file, stored in the Configuration/Objects folder, contains a series of nested XML tags that govern what objects appear where in the Insert bar. Examine this file in a text editor and you'll see that each object category is created from <category></category> tags. Within a category, each object's presence in the panel is determined by a <button/> tag. The button tag includes attributes specifying what files the object will call on, when it will appear in the panel, and what its unique identifier is. The Common category, Date object looks like this:

<category id="DW_Insertbar_Common" folder="Common">  ...  <button id="DW_Date"          image="Common\Date.gif"          enabled="true"          showIf=""          file="Common\Date.htm"/>  ...  </category>

The API for Objects

Some objects, such as the Table object, use dialog boxes to collect user information; others, such as the HR object, don't. The overall structure and procedure for both is the same.

Object File Structure

Figure 36.2 shows the HTML file for a simple object that doesn't call a dialog box. Note that the body section is empty. Also note that the objectTag() function is not called anywhere in the file. Dreamweaver will call the function automatically. Figure 36.3 shows the file for the same object, with a dialog box. The body contains a form, which will become the contents of the dialog box. Note that the form does not include a submit button. Dreamweaver will supply this.

Figure 36.2. The HTML file for a simple object that does not call a dialog box.


Figure 36.3. The HTML file for an object that does call a dialog box.


Both files contain the following key elements:

  • Filename. This becomes the Insert menu entry for the object.

  • Page title. This becomes the tooltip that pops up to identify the object in the Insert bar.

  • objectTag() function. This JavaScript function is the most important element of the object file. The function returns the exact code you want the object to insert into your document, enclosed in quotes. The objectTag() function is part of the Dreamweaver API, so it doesn't need to be defined. It also doesn't need to be called; Dreamweaver calls it automatically when the object is chosen.

  • HTML form (optional). This becomes the dialog box for collecting user input and customizing the code. Dreamweaver supplies the OK and Cancel buttons automatically.

  • displayHelp() function (optional). If there is a dialog box, and this function is defined, Dreamweaver will add a Help button to the dialog box. When the user clicks that button, the function will be executed.

In the example shown in Figure 36.2, the code returned by the objectTag() function is a simple level 1 heading. Everything between the quotation marks, in the return statement, will become part of the user's document. In the example shown in Figure 36.3, form input is collected and used to construct the return statement.

The Procedure for Objects

The API procedure for processing objects determines how and when Dreamweaver uses the file elements previously discussed. The procedure is as follows:

  1. At startup, Dreamweaver reads the insertbar.xml file, and populates the Insert bar using its entries. It also populates the Insert menu, using the filename as the menu entry.

  2. When the user mouses over the object in the panel, Dreamweaver uses the <title> from the object file to create the tooltip that will appear.

  3. When the user clicks an object, Dreamweaver reads the object file. If the file includes body content, Dreamweaver displays a dialog box containing the content, supplying OK and Cancel buttons automatically. If the file contains a displayHelp() function, a Help button also will appear.

  4. The final step in the API process is calling the objectTag() function. If there is a dialog box, the function is called when the user clicks OK. If there is no dialog box, the function is called as soon as the user clicks the object icon in the Insert bar. Whatever string of text is returned by the objectTag() function is inserted into the user's document, usually at the insertion point. (An exception to this is when the return string contains head content, such as a <meta>, <base>, or <link> tag. In this situation, even if the insertion point is in the body, Dreamweaver will insert the code into the head.)

Pretty simple, eh? To create an object extension, all you have to do is decide what code you want inserted and create a file that matches the structure shown in Figures 36.2 and 36.3. Then create an entry for the object in insertbar.xml, to make it part of the Dreamweaver interface.



Not all objects are created equal! Some items lurking in the Insert bar especially those representing server-side code for live data pages are very complex commands in object-disguise. They're way beyond the scope of this chapter.

Exercise 36.1 Setting Up Shop

In this exercise, you'll get your working space in order and learn some of the basic extension-developing features available in Dreamweaver. You will create a custom folder within the Objects folder to store your exercise objects, and add data to insertbar.xml so your custom folder becomes a custom Insert bar category.

  1. To begin with, make sure Dreamweaver isn't running. You are doing this to experiment with how and when Dreamweaver loads extensions.

  2. If you haven't done so already, make a backup copy of the Configuration folder, in case disaster strikes and you break something while tinkering with it.

  3. Find and open the Configuration/Objects folder on your hard drive. Create a new folder inside this folder. Name it Development. It's a good strategy, when you're developing new objects, to put them in a special folder called Custom or Development, at least until you're sure they're running properly.



    Never store your object files loose in the Configuration/Objects folder, or Dreamweaver won't recognize them. Objects must be placed within an existing or new subdirectory within that folder.

  4. In a text editor, open the Configuration/Objects/insertbar.xml file. Scroll to the end of the entries. Immediately above the closing </insertbar> tag, add the following code:

    <category id="DW_Insertbar_ Development" folder="Development">  </category>

    This will create a Development object category in the Insert bar, matching your Development folder.

  5. Save and close insertbar.xml.

  6. Launch Dreamweaver. At startup, the program checks the Configuration folder and loads all extensions inside.

  7. Check the Insert bar for a new category called Development. Because you added the code at the end of insertbar.xml, it should appear as the rightmost tab of the Insert bar (see Figure 36.4). Of course, if you choose that category, it'll be empty. You'll address that next.

    Figure 36.4. The new Development objects category in the Insert bar.


Exercise 36.2 Making a Simple Object

The simplest objects are those that don't call up a dialog box for user input, and therefore always return the same code. The simple object that you will create in this exercise is a copyright statement just the sort of thing you might want to put at the bottom of all your web pages.

To create this object, use the text editor of your choice. Save all exercise files in the Development folder you created in the preceding exercise.

  1. The first step when creating any object is to decide exactly what code you want the object to insert. In this case, you want a one-line piece of text, formatted however you like, utilizing the special HTML entity for . (See Chapter 4, "Working with Text," for more on creating HTML entities, such as the copyright symbol.) Figure 36.5 shows the copyright statement with formatting applied.

    Figure 36.5. Formatting the Tom Thumb copyright statement for inclusion in an object file.




    Use Design view to create and format the copyright statement; then go to Code view and the code will be there, written for you.

  2. Next, create the basic object file, with all structural elements in place. Open your text editor and enter the basic required code for an object without dialog box. You can leave out the details specific to this object, for now. Your code framework should look like this (elements that you will be replacing later with custom text appear in bold):

    <html>  <head>  <title>Title Goes Here</title>  <script language="JavaScript">  function objectTag() { return 'inserted code goes here';  }  </script>  </head>  <body>  </body>  </html>


  3. Enter a page title into the code. This will become the tooltip that shows in the Insert bar. A logical title for the current file might therefore be Tom Thumb Copyright Info. The top portion of your code should now look like this (new code is in bold):

    <html>  <head>  <title>Tom Thumb Copyright Info</title>


  4. Insert the desired line of code as the return statement of the objectTag() function. If you have the line of code already typed into your computer, you can just copy and paste it in; otherwise, type it in manually now.

    Note that the entire return statement has to be in quotation marks. They can be single or double quotes; just make sure they're in balanced pairs.

    Your code should now look like this (new code is in bold):

    <html>  <head>  <title>Tom Tumb Copyright Info</title>  <script language="JavaScript">  function objectTag() { return '<font face="Verdana, Arial, Helvetica, sans-serif" size="2">&copy; Tom Thumb,  graphics/ccc.gif2001</font>';  }  </script>  </head>  <body>  </body>  </html>



    As with any JavaScript return statement, no hard returns can occur within the statement. Make sure your code is written out in one long line, or it won't work!

  5. Save your file in the Development folder. Call it Tom Thumb Copyright.htm. The filename will become the menu command that appears in the Insert menu; so it's good practice to name it something descriptive. Capitalization and spacing also will carry through to the menu entry. (The extension can be.htm or.html Dreamweaver accepts either.)



    You can get more control over how the object name appears in the Insert menu by editing Configuration/Menus/menus.xml.

  6. To make the new object appear in the interface, you'll need to add a <button/> tag to insertbar.xml. Quit Dreamweaver, if it's running, and open insertbar.xml in your text editor. Find the Development category tag you added earlier, and add the following code (new code is in bold):

    <category id="DW_Insertbar_Development"folder="Development">      <button id="DW_Development_TomThumbCopyright"       image=""       enabled="true"       showIf=""      file="Development\TomThumbCopyright.htm"/>  </category>


  7. Test your object! Launch Dreamweaver and create a new document, if there isn't one already open.

  8. Check the Development category of the Insert bar; the new object should be there, represented by its name rather than by an icon. Position the cursor over the name and the tooltip should appear (see Figure 36.6).

    Figure 36.6. The new custom object, with tooltip.


  9. While you're at it, check the Insert menu. Your new object will appear at the bottom of the menu, identified by its file name.



    Don't waste your time making custom icon files for objects while they're still in the development phase. Wait until the object is all polished and perfectly functioning; then dress it up with a custom icon. (Exercise 36.5 shows how to make an icon file.)

  10. Make sure you're in Design view and click the object. The desired code should be inserted into the document at the current cursor position. Congratulations! You've made your very first object.



What If It Doesn't Work?

If your object doesn't show up in the Insert bar at all, you either saved it in the wrong place, didn't append the .html extension to the filename, or you might have a syntax error in the insertbar.xml file.

If your object shows up, but something is wrong with the code, you'll probably get an error message when Dreamweaver tries to execute the objectTag() function. Dreamweaver error messages are fairly specific in what went wrong and what needs fixing. Examine the message and fix your code accordingly.

Exercise 36.3 Creating an Object with a Dialog Box

Your simple object is fine as far as it goes, but it's not a very flexible or useful object because it always returns the same code, no matter what. What if you want to assign a copyright to someone besides good old Tom Thumb? A fully functional object would bring up a dialog box that would ask for user input, and would enter that information into the code. That's the object you will build in this exercise.

  1. Open Tom Thumb Copyright.htm (from the preceding exercise) and save it as Copyright Statement.htm in the Development folder. Why reinvent the wheel? You can just build on your previous success by adding a dialog box and tweaking the objectTag() function's return statement to collect user input.

  2. Change the <title> of the new object file to Copyright Statement.

  3. Decide what pieces of the code you want to replace with user input. Check Figure 36.5 as a reminder of what the end product should look like. For this object, you want to ask the user for a copyright name (rather than Tom Thumb) and a copyright year. (If your JavaScript skills are up to it, you could have Dreamweaver automatically calculate the year; for this exercise, just ask the user to insert it.)

  4. Create an HTML form that will serve as a dialog box to collect this information. To be functional, your form needs two text fields: one to collect the name and another to collect the year. So the simplest form you could possibly come up with might look something like the one shown in Figure 36.7.

    Figure 36.7. The form for the Copyright Statement object dialog box as it appears in Dreamweaver Design view.




    If you want to improve your skills creating user-friendly forms, pay attention to all the user interface elements in Dreamweaver. The dialog boxes, inspectors, and panels are beautiful examples of clean, transparent interface design; and they're constructed almost entirely from standard form elements.

  5. Open Copyright Statement.htm and build the form in the body section of that file. If you like coding forms by hand, go to it. If you would rather use a visual editor, open the file in Dreamweaver and use Design view to build it, as is shown in Figure 36.7.



    If you're building your form in the Dreamweaver visual editor, method and action properties will be automatically added to the <form> tag. Your form doesn't need either of those because the form isn't going to be processed in the standard way. You can safely remove these properties from your code. Dreamweaver also will add background and text color properties to the <body> tag; you should remove these and let the software's UI controls determine the appropriate color scheme for the dialog box.

    Your form code should look like this:

    <form name="theForm">  <table>    <tr valign="baseline">           <td align="right" nowrap>Name:</td>           <td align="left">                  <input type="text" name="name" size="30">           </td>    </tr>    <tr valign="baseline">           <td align="right" nowrap>Year:</td>           <td align="left">                  <input type="text" name="year" size="10">           </td>    </tr>  </table>  </form>

    Note that neither the table nor the text has any formatting in them. Dreamweaver will supply the formatting when it processes the extension. If you enter your own formatting, your dialog box won't meet Macromedia user interface guidelines, and might not look good on all computers. So don't do it!

  6. Okay, your form is pretty; to make it functional, you need to rewrite the return statement of the objectTag() to include the collected user input. If you're an old coding hand, this will be a piece of cake. If you're a novice at JavaScript, the trickiest bit is balancing the opening and closing quotes, so you don't end up with any unterminated string literals. Your objectTag() function should now look like this (new code in bold):

    function objectTag() { return '<font face="Verdana, Arial, Helvetica, sans-serif" size="2">&copy;  '','+document.theForm.year.value+' </font>';  }



    If you think the return statement is too unwieldy to read easily, you could collect the form input into variables and use those to construct the final statement.

  7. Quit Dreamweaver, if it's running. To add the new object to your Insert bar, open insertbar.xml and add the following code to your Development category tag:

    <button id="DW_Development_CopyrightStatement"   image=" "   enabled="true"   showIf=""   file="Development\CopyrightStatement.htm"/>


  8. Launch Dreamweaver, and create a new document to try out your new object. You should get a lovely dialog box that looks like the one shown in Figure 36.8.

    Figure 36.8. Dialog box for the Copyright Statement object.




    As with all objects, you'll get a different experience inserting into Code view than you will in Design view. If you're in Code view (or in Code and Design view, with the code portion of the Document window active), be careful to position the cursor in between the <body></body> tags, and not in the middle of any existing tag code, before inserting.

  9. When you fill in your information and click OK, a customized copyright statement line should appear in your document.



What If It Doesn't Work?

As with the earlier exercise, if there's a problem with your code, Dreamweaver should give you a helpful error message. Read the error message, try to guess what it means, and then go back to your code and look for problems. Compare your code to the code listed in this exercise to see what might be wrong.

The most common things that go wrong in this kind of object file are incorrect reference to form elements and mismatched single and double quotes in the return statement.

Exercise 36.4 Refining Your Object

This exercise shows that, although the only required JavaScript function for an object is the objectTag() function, you can add other optional functions. In fact, you can define any function you want to in the head section of the object file. Additional, locally defined functions can be explicitly called from any part of the interface, including the <body> (onLoad) or any of the form elements (onClick, onBlur, and so on).

The local function you'll add in this exercise addresses a minor annoyance you might have noticed in your object's dialog box. When the dialog box appears, the insertion point might not be in the correct position for you to immediately start entering data. Not a life-threatening problem, but less than slick.

  1. Open the Copyright Statement.htm file in your text editor. Because this is not major surgery, you will work on the same object you created in the preceding exercise, instead of creating a new object.

  2. Add an initializing function to the document head. Somewhere inside the <script> tags in the document's head section, add the following code:

    function initializeUI(){;;  }

    What does this function do? The first line officially gives focus to whatever form element is named within it in this case, the name field (your first text field). The second line selects the text (if any) in whatever form element is named within it again, in this case, the name field.



    This function is used in many of the objects that ship with Dreamweaver. (Macromedia does not prohibit borrowing pieces of code.) Because the function is not part of the API, there's nothing magic about its name. If you would rather name it something different, feel free to do so.

  3. To call the function, add the following code to the <body> tag of the object file:

    <body onLoad="initializeUI()">

    Because this function is not part of the Dreamweaver official object-handling procedure, it must be specifically called.

  4. Try it out! Save and close the object file. Quit and relaunch Dreamweaver, and choose the object from the Insert bar. The insertion point will be primed and ready to enter data into the Name field of the dialog box.

Exercise 36.5 Adding an Object Icon

  • Professional-looking objects have their own icons. When the development phase of your object is finished, the final touch is to make an icon file to represent it in the Objects panel.

    The requirements for an icon file are as follows:

  • The file must be a GIF image file, preferably no larger than 18x18 pixels. (Larger images will work, but they'll be squashed into an 18x18 pixel space in the panel.)

  • The file should have exactly the same name as the object file it goes with, but with the.gif extension. For this exercise, therefore, name the image Copyright Statement.gif.

  • The file should be stored in the same folder as the object file it goes with. For this exercise, the icon file must be stored in the Development folder.

  • The icon must be called on in insertbar.xml, by adding the image attribute to the <button> tag.

Icon files can have any colors you like, and the icon can look like anything you can imagine. You'll quickly discover, however, that designing icons that clearly communicate what they represent, when there are only 324 pixels to play with, is a real art.

  1. Create, adapt, or borrow an 18x18 pixel GIF file containing an icon. If you have access to a good graphics program (such as Macromedia Fireworks), and want to create your own icon, do it. Otherwise, use the Copyright Statement.gif file in the chapter_36 folder on the CD. (The image in this file is just a big fat symbol, which is not hard to create.)

  2. Put the icon file in the Development folder. The icon has to be stored in the same folder as the object file, remember.

  3. Quit Dreamweaver. Then open insertbar.xml in your text editor and add the following code to your <button/> entry (new code is in bold):

    <button id="DW_Development_CopyrightStatement"  image="Development\CopyrightStatement.gif"  enabled="true"  showIf=""  file="Development\CopyrightStatement.htm"/>


  4. Launch Dreamweaver, create a new document if needed to activate the Insert bar, and take a look at your icon! Figure 36.9 shows the Development folder, with a cool custom icon in place.

    Figure 36.9. The Copyright Statement object as it appears in the Insert bar with its new custom icon in place.


Making the Most of Objects

Congratulations! You now know the foundation skills for making Dreamweaver objects. How can you make objects work for you? As you have seen, any piece of HTML code that you repeatedly use in web pages is a candidate for an object. The best object candidates, however, are pieces of code that you need to customize and then insert changing the name and email address, specifying a certain URL to link to, and so forth.

Any time you find yourself going through the same steps over and over as you add content to web pages, ask yourself the following:

  • Is the code I'm inserting similar enough each time that I could create an object from it?

  • Are there differences in the code each time, or is it exactly the same code? (If the code is exactly the same each time, requiring no customization, it might be more efficient to use a recorded command or snippet.)

  • How many more times do I think I'm likely to need to insert this code? Will my need continue after today? After the current assignment? Indefinitely? Creating an object is a time-consuming solution (not smart for a need that is only very temporary).

  • Do I have some extra time right now to devote to making this object? (Never try a new, challenging solution when your deadline is 45 minutes away.)

Depending on your answers, you'll know whether it's time to crack open Dreamweaver and fit a new custom object inside.

Creating Command Extensions

Commands are those extensions that appear as entries in the Commands menu. (Actually, if you manipulate the menus.xml file as discussed in the Chapter 34, "Customizing Dreamweaver," you can make commands appear in any menu. But they appear in the Commands menu by default.) They are the most versatile and powerful of the extension types, enabling you to perform almost any edits on a document or site. Their API requirements are simple; yet, because they are so flexible, they are not easy to master. This section covers what's involved in creating simple (and also not-so-simple) Dreamweaver commands.

Commands in the Configuration Folder

Like all extensions, commands are made from HTML and JavaScript. Each command consists of an HTML file (the command file itself) and optional, associated JS files and/or graphics. Command files are stored in the Configuration/Commands folder. By default, all files in this folder will appear in the Commands menu.



If you have ever recorded commands, or saved history steps as commands, you've created simple command files! Look in the Configuration/Commands folder and you'll find an HTML file for every saved command. The filename will be the name you gave the command when you saved it.

The API for Commands

Like objects, commands can exist with or without dialog boxes. They can be simple or complex. A number of API-defined functions can be part of the command file, but the file also can be very simple, with no special functions. The API procedure will be simple or complex, based on the file structure. (Note also that these are flexible extensions!)

Command File Structure

There are no required API functions for commands, although a variety of optional functions exist. Figure 36.10 shows a very basic command file, with only required elements in place. Note that the body section is empty. Note also that there are no API functions, and the main function is called onLoad.

Figure 36.10. The HTML file for a simple command that does not call a dialog box.


This kind of file has the following elements:

  • Filename. The filename, minus its extension, will become the menu entry. Command filenames can include spaces, and capitalization is respected.

  • Main function. This is the function that makes the command do whatever you want it to do. It's a locally defined function, not part of the API, which means it must be called explicitly. If the command has no dialog box, the function should be called in the <body> tag, using the onLoad event handler. If the command has a dialog box, the function should be called as part of the commandButtons() function (described in the following list).

Believe it or not, that's all that's absolutely required of a command file without dialog box.

If the command includes a dialog box, a few more API elements are required. Figure 36.11 shows a sample command file with dialog box, again containing only the necessary elements. Note that the form does not include a submit button. The main command is now called from the commandButtons() function, not from the <body> tag.

Figure 36.11. The HTML file for a command that calls a dialog box.


The required elements for a command that calls up a dialog box are as follows:

  • Page title. The title is required if the command includes a dialog box, and will become the title of the command's dialog box, if there is one. If there isn't a dialog box, the title is not required.

  • HTML form. As with all extensions, this will create the user interface (in this case, the dialog box). Note that, as with objects, the form does not include a submit button. Unlike objects, however, command dialog boxes are not automatically supplied with buttons; instead, command buttons must be defined and given functionality using the commandButtons() function.

  • commandButtons() function. If there is a dialog box, this function creates the buttons that will appear. If this function doesn't exist, the user will have no way to activate or close the dialog box! The commandButtons() function must return an array consisting of the name of each button, followed by the code to be executed when the button is clicked. Note that because the main command function must be called here, it should no longer be called using the <body> tag's onLoad handler.

In addition to these required elements, several optional API functions can be included. The most useful of these is canAcceptCommand(). This function determines whether the command should appear grayed out (that is, disabled) in the menu. A command that operates on the contents of a document, for instance, shouldn't be accessible if there is no document open. If the function returns true, the command will be accessible; if it returns false, the command will be grayed out. The API includes a whole slew of enablers (functions that determine whether something is possible) to help with this.

The Procedure for Commands

The API procedure for processing commands determines how and when Dreamweaver uses the file elements discussed in the preceding section. The procedure is as follows:

  1. When the user clicks the Commands menu, Dreamweaver looks through all files that should appear in the Command menu, checking each for the canAcceptCommand() function. If it's present, and returns false, that command will be grayed out in the menu. If it's not present, or returns true, the command will be available.

  2. When the user chooses a command from the menu, if there is no form, Dreamweaver executes whatever function is defined in the <body> tag's onLoad handler, and the procedure is complete.

  3. If the command file does include a form, Dreamweaver calls the commandButtons() function to determine what buttons to add to the form. It then calls any function called onLoad (such as an initializeUI() function). It then presents the dialog box, displaying the <title> in the dialog box's title bar.

  4. When the user clicks any of the buttons in the dialog box, Dreamweaver executes the code attached to that button by the commandButtons() function. Typically, an OK button calls the main function and closes the window; an Apply button calls the main function but doesn't close the window; a Cancel button just closes the window. Note that the dialog box will not close until one of the buttons uses the window.close() statement.

So far, it all sounds pretty simple. The complex aspect of commands is that you usually want them to act on documents. And acting on documents means dealing with the Dreamweaver DOM.

The Dreamweaver DOM

If you've worked in depth with JavaScript before especially if you've created DHTML effects using JavaScript you're already familiar with the concept of the document object model (DOM). The DOM is the hierarchical, or tree, structure of objects (tags, pieces of text, and so on) that makes up an HTML document. To gain access to any part of the document, you must navigate up and down the hierarchy, or climb up and down the tree.



If you've ever torn your hair out struggling with the conflicting DOMs of Internet Explorer and Netscape, working with Dreamweaver commands will be a welcome relief, because there's only the Dreamweaver DOM to worry about.

Understanding Objects (Nodes)

An object is any page element that you can control by scripting. They have properties that you can access and change, and methods that represent things you can do with them. Objects are also called nodes.

Parents, Children, and Siblings

Just as an HTML document is constructed from tags nested inside each other, and text blocks nested inside tags, so objects, or nodes, can have parents, children, and siblings. In the following example, for instance, The <ul> object is the parent node of the three <li> objects, which are siblings of each other:

<ul>          <li>Moe</li>          <li>Larry</li>          <li>Curly</li>  </ul>

The text block Moe is the only child node of the first <li> object. And so on. Figure 36.12 shows a typical document diagrammed as a tree of objects.

Figure 36.12. A simple HTML document shown as it appears in Dreamweaver and as a diagrammed document tree.


Node Types

There are four kinds of objects, or nodes, in a document:

  • The document node type. The document itself, as an entity.

  • The element node type. All HTML tags belong to this type.

  • The text node type. Each block of text is an object of this type.

  • The comment node type. HTML comments.

In the preceding example, the Moe object is of the text node type; its parent <li> object is of the element node type. Different node types have different properties and methods. Tables 36.1 through 36.4 list the properties and methods of the different node types, as they exist in the Dreamweaver DOM.

Table 36.1. DOCUMENT_NODE Objects


Return Value (r) Indicates Read-Only


9 (r)


Null (r)


Object representing the document's parent window (r)


NodeList containing all children (r)


The <html> tag element (r)


The <body> tag element


The absolute address of the document (or an empty string, if the document hasn't been saved)

getElementsByTagName (tagName)

NodeList containing all instances of the given tag



Table 36.2. ELEMENT_NODE Objects


Return Value (r) Indicates Read-Only


1 (r)


The parent tag (r)


NodeList containing all immediate children (r)


HTML name for the tag (TABLE, A, IMG, and so on) (r)


String containing the value of the specified tag attribute


HTML code contained within the opening and closing tags of the element


HTML code contained within the tag, and the opening and closing tags


Value of the attrName attribute

setAttribute (attrName, attrValue)

removeAttribute (attrName)


NodeList of children of the current element that are (tagName)tagName elements



Table 36.3. COMMENT_NODE Objects


Return Value (r) Indicates Read-Only


8 (r)


Parent tag (r)


Empty NodeList (r)


String of text between the opening and closing comment tags



Table 36.4. TEXT_NODE Objects


Return Value (r) Indicates Read-Only


3 (r)


Parent tag (r)


Empty NodeList (r)


String of text that comprises the current object



Gaining Access to the DOM

In addition to all the standard JavaScript means for accessing and controlling DOM objects, the Dreamweaver API includes the document, or dom, object and its methods. These are the primary methods you use to edit documents using Dreamweaver extensions. Before you can use any of these methods on a document, however, you have to officially gain access to the document's structure by using the dw.getDocumentDOM() function. Table 36.5 lists the specifications of this function. This function enables you to gain scripting access to the contents of user documents.

Table 36.5. Specifications for dw.getDocumentDOM()




This function creates a DOM object, giving access to the contents of a document's object structure.


No arguments are required. If no arguments are present, the currently active document will be used as the source of the DOM object. Optional arguments:

document parent parent.frames[number] parent.frames['framename']

A URL. (URLs must be absolute or relative to the extension file.)


The document object at the top of the DOM hierarchy (DOCUMENT_NODE type).

You access the current user document's DOM by assigning it to a variable, like this:

var theDOM=dw.getDocumentDOM();

After you have done this, you have access to an object of the first node type previously listed. You are officially climbing the document tree. You can now use the methods and properties of the various nodes to navigate through the document and edit it, as in these examples:

//change the background color to black  var theDOM=dw.getDocumentDOM();  var theBody=theDOM.body;  theBody.bgcolor="#000000";  //determine what kind of object the current selection is  var theDOM=dw.getDocumentDOM();  var theSel=theDOM.getSelectedNode();  if (theSel.nodeType=="1") {       window.alert(theSel.tagName);        } else if (theSel.nodeType=="3") {       window.alert(;        }

The subject of DOM access is much bigger than this chapter covers, and it takes practice to master. But the rewards are great. After you know how to navigate a document, you can use your command or other extension to tell Dreamweaver to do almost anything to a user document. (Such power!)



For more information on working with the DOM, and scripting extensions in general, read Dreamweaver MX Extensions, published by New Riders; or Building Dreamweaver 4 and UltraDev 4 Extensions, published by Osborne.

Exercise 36.6 Making a Simple Command

In this exercise, you will create a command that finds all the images in an open document and assigns them a border width of 2. You won't need a dialog box, so this will be a simple file to create. You will, however, get some practice accessing the DOM.

  1. In your text editor, create a new HTML file. Save it in the Configuration/Commands folder as Set Image Border.htm. Enter the basic code framework for a command with no dialog box. You will leave the details blank for now, like this (placeholder code in bold):

    <html>  <head>  <title>Set Image Border</title>  <script language="JavaScript">  function setImageBorder() { //command code will go here  }  </script>  </head>  <body onLoad="setImageBorder()">  </body>  </html>

    In this example, you have set the <title>, although it won't be called on. You have also created a local function, setImageBorder(), and called it onLoad. That's all the framework you need.

  2. The only remaining step is to fill in the main function code. Before tackling accessing the DOM, plan out the required functionality for setImageBorder(). Using the dw.getDocumentDOM() function, and the node methods and properties listed in Tables 36.1 through 36.4, you can determine that your function needs to do the following new code in bold:

    function setImageBorder() { //get document access  //get image access (collect images as an array)  //set the border property of each array item  }



    Plotting out the main steps of a function, as comments inside the function, can help whittle major scripting tasks into manageable chunks.

  3. You'll start by getting document access (new code in bold):

    function setImageBorder() { //get document access  var theDOM=dw.getDocumentDOM();  //get image access (collect images as an array)  //set the border property of each array item  }


  4. Next, you'll climb up the tree to get the images. Table 36.1 shows that the document node type object has a property called body, which gives you access to the <body> tag. Because the images are all in the body, you'll start with that. Then, because the <body> tag is of the element node type, you'll use its getElementsByTagName() method to collect all the body's <img> tags into an array. Like this:

    function setImageBorder() { //get document access  var theDOM=dw.getDocumentDOM();  //get image access (collect images as an array)  var theBody=theDOM.body;  var theImages=theBody.getElementsByTagName("IMG");  //set the border property of each array item  }


  5. You have now collected the images into an array of objects of the element node type. As Figure 36.13 shows, any attribute of a tag can be accessed as an object property. So you can step through the image array, setting the border property to 2, as follows (new code in bold):

    function setImageBorder() { //get document access  var theDOM=dw.getDocumentDOM();  //get image access (collect images as an array)  var theBody=theDOM.body;  var theImages=theBody.getElementsByTagName("IMG");  //set the border property of each array item  for (var a=0;a<theImages.length;a++) {    theImages[a].border="2";    }  }
    Figure 36.13. The form for the Set Image Border dialog box as seen in Dreamweaver Code and Design views.


  6. That's all there is to it! Save your document and close it. If Dreamweaver is running, quit. Then launch Dreamweaver and open a document that has several images in it.



What If It Doesn't Work?

If your command file contains a syntax error, Dreamweaver will give you a handy error message as soon as you try to choose it. Read the error message, go back to your file, and find the error.

If your object doesn't cause any errors, but doesn't change any images, there's a logic error. Probably you didn't accurately access the DOM. The getElementsByTagName() function requires that all parameters be specified in uppercase, so make sure your code refers to IMG, not img, or it won't work. Make sure all of your variable names match up, as you proceed into the document tree. Match your code against the code shown here, and keep tinkering until it works.

Exercise 36.7 Creating a Command with a Dialog Box

The command so far is handy if users want a 2-pixel border around their images. How about letting the user specify how wide the border should be? (The ability to set the border to 0 might come in handy, if you ever inherit someone else's HTML pages from a web editor that doesn't set that feature automatically.) You'll now add a dialog box to the command created in the preceding exercise, asking for a width.

  1. In your text editor, open the Set Image Border.htm command file and save it as Set Image Border 2.htm.

  2. Create a simple form in the body section of the file. As always, you can code the form by hand or open the file in Dreamweaver and create the form in Design view. Figure 36.13 shows how the form might look when complete.

    Wherever you create the form, remember to name it in the examples here, the form is named theForm, and the name of the text box is width.

  3. Because there's now a form, you need to add the commandButtons() function. You will want an OK button that calls the main function and closes the window; an Apply button that calls the main function but doesn't close the window; and a Cancel button that just closes the main window. The code will look like this:

    function commandButtons() { return new Array("OK","setImageBorder(); window.close();","Apply", "setImageBorder()",  graphics/ccc.gif"Cancel","window.close()");  }

    After you've done this, be sure to remove the function call from the <body> tag. You don't want the main function to execute as soon as the dialog box opens!

  4. Finally, you need to adjust the main function so that it includes the form input collected in the dialog box. Rewrite the statement inside the for loop like this new code in bold:

    for (var a=0;a<theImages.length;a++) {   theImages[a].border=document.theForm.width.value;    }


  5. Try it out! Your dialog box should look like the one shown in Figure 36.14. Make sure the commands get executed properly and that all three command buttons behave as they're supposed to.

    Figure 36.14. Dialog box for the Set Image Borders command.


Exercise 36.8 Refining Your Command

You can improve the functionality of this little command in all sorts of ways. Maybe you just want to set the border for images with, or without links? Maybe you want to enable the user to choose which images get borders? Maybe you want to give the user the opportunity to remove the border attribute completely? With DOM access, all is possible. (To work with linked images, just determine which <img> tags have an <a> tag as their parent node.) For now, however, add the canAcceptCommand() function. If the current document doesn't have any images, it makes no sense for the command to be available. So you'll return true if there are images, and false if there aren't.

  1. In your text editor, open the Set Image Borders 2.htm command file. Add the framework for the new function, along with an indication of what you want it to do:

    function canAcceptCommand() { //access the document  //if there is no document, return false  //access the body  //access the images, collected as an array  //if the array is empty, return false  //otherwise, return true  }


  2. As you might have noticed, the first several steps are the same as those in your main function. You can just copy and paste that code into this function, and then tack on a conditional, like this:

    function canAcceptCommand() { //access the document  var theDOM=dw.getDocumentDOM();  //if there is no document, return false  if (!theDOM) return false;  //access the body  var theBody=theDOM.body;  //access the images, collected as an array  var theImages=theBody.getElementsByTagName("IMG");  //if the array is empty, return false  if (theImages.length=="0") return false;  //otherwise, return true  else return true;  }


  3. Try your command now, to see how it works. First, try it on a document with images, then one without.

Making the Most of Commands

Are you already full of ideas for your next command? If so, there's no stopping you. If not, you might just need to broaden your horizons a little bit. Try these inspiration generators:

  • Whenever you're working in Dreamweaver, keep a notebook handy. If you find yourself repeating the same manual procedure over and over, wasting time performing tedious tasks, try to imagine what kind of command could be written, to help you out. Jot that inspiration down.

  • Take a spin through the Extending Dreamweaver manual, especially the list of API methods that takes up the last half of the book. Just seeing all the different things you can tell Dreamweaver to do is likely to get your imagination moving.

  • Unless you enjoy coding for its own sake, don't spend hours and hours writing a command before you check out the Exchange. You might come across an already completed one that does just exactly what you need.

The more you work with the DOM, the easier it will be. Pretty soon, you'll be wanting to create custom property inspectors, floating panels, reports, translators, and more.

Packaging Your Extensions

The Extension Manager has become the standard method for installing and sharing extensions. Although you could share your extensions by just giving away the raw files, along with instructions on where to put them, it's much safer, and user-friendlier, to provide an installation package, or MXP file for use with the Extension Manager.

Lucky for us, the Extension Manager not only installs extensions, it also packages them up neatly into special installation files. The process is even relatively painless. Just follow these steps:

  1. Put all the required files (help files, HTML files, JS files, GIF icons) in one folder, outside the Configuration folder.

  2. Create an installation file. This is an XML document with the filename extension.mxi, which contains all the instructions needed for installation: where the files should be stored, what versions of Dreamweaver and what platforms the extension requires, author's name, type of extension, and description. The formatting required is very exact. The best approach for beginners is to start from the Samples included with the Extension Manager. These files include a blank file (blank.mxi) to use as a template and a sample file (sample.mxi) filled in with information for a simple command.

  3. Launch the Extension Manager, and go to File > Package Extension.

Figure 36.15 shows a sample folder containing all the proper files to package the Copyright Statement file.

Figure 36.15. The assembled elements of the Copyright Statement object all ready for packaging.


Exercise 36.9 Packaging an Extension

This last exercise will take you through the steps to create an MXP file from this extension.

  1. Start by copying all needed files into one folder. Somewhere on your hard drive, outside the Configuration folder, create a new folder. Name it whatever you like and will remember. (Something like Copyright Statement Files, maybe?)

    Find the files that make up the object, and copy them there. This will include Copyright Statement.htm and Copyright Statement.gif.

  2. On your hard drive, find the Extension Manager application folder. Inside that folder, find the Dreamweaver/Samples folder. Inside there, you'll see blank.mxi. (Figure 36.16 shows where to find these items.) Duplicate that file in your Collection folder, and call it C_Statement.mxi. (Naming conventions apply here no spaces or special characters, no long names.)

    Figure 36.16. The Extension Manager application folder structure showing sample.mxi and blank.mxi.


    After you've made the duplicate file, open it in your text editor.



    You can download a PDF file containing detailed instructions for creating installation files from the Macromedia web site. Go to the Macromedia Exchange for Dreamweaver page (, and click the Site Help topic Macromedia Approved Extensions.

  3. Fill in the blanks with the information for your object.

    The blank file has all the framework you need. By examining the sample file, you can get an idea how it should be formatted. For your extension, fill in the blanks until your code looks like that shown in Listing 36.1. Information that has been added to the framework from blank.mxi is in bold. Pay special attention to the following when filling in the code:

    Listing 36.1 The Complete Code for C_Statement.mxi
    <macromedia-extension        name="Copyright Statement"        version="1.0.0"        type="object">        <!-- List the required/compatible products -->        <products>              <product name="Dreamweaver" version="3" primary="true" />        </products>        <!-- Describe the author -->        <author name="Tom Thumb" />        <!-- Describe the extension -->        <description>        <![CDATA[       Inserts a formatted copyright statement, with user input for name and  year.        ]]>        </description>        <!-- Describe where the extension shows in the UI of the product -->        <ui-access>        <![CDATA[       Access this extension via the ThumbThings tab in the Insert bar.        ]]>        </ui-access>        <!-- Describe the files that comprise the extension -->        <files>              <file source="Copyright Statement.gif"  destination="$dreamweaver/configuration/Objects/ThumbThings/Copyright  Statement.gif" />  <file source="Copyright Statement.htm"  destination="$dreamweaver/configuration/Objects/Thumbthings/Copyright  Statement.htm" />         </files>         <!-- Describe the changes to the configuration -->         <configuration-changes>                <insertbar-changes>                       <insertbar-insert insertAfter="DW_Insertbar_Server">                              <category folder="ThumbThings"  id="DW_Insertbar_ThumbThings">                            <button enabled=""  file="ThumbThings\Copyright Statement.htm" id="DW_ThumbThings_Copyright"  image="ThumbThings\Copyright Statement.gif" showIf="" />                            </category>                      </insertbar-insert>                </insertbar-changes>        </configuration-changes>  </macromedia-extension>
    • For the author name. Enter your name. (You've already entered Tom Thumb, Big-Time Genius there's no law against being fanciful.)

    • For the filenames. Enter the relative path from the MXI file you're creating to the copies of the extension files you've saved for packaging. If all these files are in the same folder, you can just enter the filename.

    • For the destination. Enter the complete path from the Dreamweaver application folder root, as shown. If you want your extension to create any new folders in existing folders, enter them as part of the path. (You have entered ThumbThings to create a new folder within the Objects folder.)

    • For the version number. Your extension, like any other piece of software, gets its own version number. Start with 1.0, and increment the number if you later revise the extension.

  4. Finally, you package everything together with the Extension Manager. Launch the Extension Manager, and go to File > Package Extension. For the name of your extension, choose something descriptive that obeys the standard naming conventions (no empty spaces, no more than 20 characters, no special characters). It's good practice to use the same name you used for the MXI file, just to keep your own file organization tidy. Make sure you leave the.mxp extension in place.

    When you're asked to choose a file, choose C_Statement.mxi.

    If there aren't any problems, the Extension Manager will generate an extension file in the same folder as the MXI file. If there are problems, you'll get an error report. Most often, these are problems with the MXI file. Back to your text editor, fix the reported errors, and try again. Figure 36.17 shows how this process will look in the Extension Manager.

    Figure 36.17. The steps through the packaging process as they appear in the Extension Manager.


  5. Now use the Extension Manager to install the new extension. Start by quitting Dreamweaver, if it's running. Open the Configuration/Objects folder and remove the development version. Then open insertbar.xml and delete the code that created your Development category. Finally, install the MXP file, using the Extension Manager. (See Chapter 35 for a full discussion on using the Extension Manager to install MXP files.) If everything's hunky dory, you should get an alert message telling you the extension was installed successfully.

    Your custom extension also should now appear in the Extension Manager window (see Figure 36.18).

    Figure 36.18. The Extension Manager window showing the installed Copyright Statement object.


  6. Finish up by launching Dreamweaver and checking that everything installed correctly.

Submitting Your Extension to the Macromedia Exchange

The ultimate in sharing is submitting your extension file to the Macromedia Exchange. After you have the MXP file, the procedure is simple: Go to the Macromedia Exchange web site and click the Submit button at the top of the page. Then follow the instructions to submit (see Figure 36.19).

Figure 36.19. The Macromedia Exchange home page with Submit button.


After you have submitted an extension, Macromedia engineers will run it through a series of tests. One of three things will happen:

  • If it fails, it gets returned to you with comments.

  • If it passes the basic tests, it gets put on the web site with Basic Approval.

  • If it also passes the more comprehensive tests, it becomes a Macromedia Approved Extension.

To learn more about the testing process and how to get your extensions accepted and approved, visit the Dreamweaver web site, and click any one of the Site Help FAQ topics. This will take you to an extensive categorized list of questions and answers.


You already know Dreamweaver is a terrific web-editing environment. This chapter has showed you how you can make it into a perfectly personalized web editor for your workflow needs. As much as you have seen, however, you've only touched the surface of all that is possible with extensions. Check out the Extending Dreamweaver manual. Visit the Exchange web site and read the various support files there. If you're really serious, you can join the Extensibility Newsgroup (go to dreamweaver/extend/form/). Dust off your JavaScript books. And start rewriting history.


Inside Dreamweaver MX
Inside Dreamweaver MX (Inside (New Riders))
ISBN: 073571181X
EAN: 2147483647
Year: 2005
Pages: 49 © 2008-2017.
If you may any questions please contact us: