Thursday, September 19, 2024

Extending ColdFusion Studio

We all know and dearly love ColdFusion Studio (and its little brother HomeSite). We all have favorite features, we all have our own little tips, tricks, and settings, and we all find ways to make it work as suits as best.

For more tutorials and articles like this one, visit the Macromedia DevNet

Expand your web development skills with sample applications and other resources contributed by the Macromedia developer community and Macromedia employees.
But what many of us don’t know is just how extensible and configurable ColdFusion Studio really is. And so in this article I’d like to introduce you to one of the ways to extend this product – Tag Editors.

Note: Although I refer to “ColdFusion Studio,” everything covered in this article applies equally to HomeSite, ColdFusion Studio, and the new JRun Studio.

Understanding Tag Editors
One of ColdFusion Studio’s most powerful help features are its tag editors. These are the little dialog boxes that pop up when you right-click on a tag and select Edit Tag (or press Ctrl-F4). An example of a tag editor is shown in Figure 1.


Figure 1: Tag Editors are one of the most powerful ways to get help in Studio and HomeSite.

The beauty of tag editors is that they are not hard-coded into the product; rather, they are created on the fly. When a tag editor is to be displayed, its definition is read from a special file, and Studio uses that information to create the dialog. Those special files can be edited (or created) as needed.

Installing Tag Editors
If you’ve ever downloaded a tag from the Developer’s Exchange (at http://devex.allaire.com/developer/gallery) it may have come with a file with a VTM extension. That file is the tag editor definition file, and it is installed simply by placing it beneath the TagDefs directory (for ColdFusion Studio 4.5, this is usually C:Program FilesAllaireColdFusion Studio 4.5ExtensionsTagDefs). When ColdFusion Studio needs to display a Tag Editor, it automatically scans that directory tree to find the appropriate VTM file.

How are VTM files associated with tags? By their names. The VTM for the HTML tag is TABLE.VTM, and the VTM for the CFML tag is CFQUERY.VTM. (If you’ve ever right-clicked on a tag in ColdFusion Studio only to find the Edit Tag option grayed out, it is because no matching VTM file was found).

ColdFusion Studio comes with VTM files for all of the standard HTML, CFML, and even WML tags. But if you write your own tags or download third-party tags, ColdFusion Studio won’t be able to display a tag editor unless a matching VTM file has been created and installed.

Understanding VTML
VTM files are created using a special XML-based language called VTML (for Visual Tool Markup Language). Before you groan at having to learn yet another language, let me assure you that this one is easy to learn; if you can handle HTML and CFML, you’ll manage VTML just fine.

So, what exactly is VTML? Well, what HTML does for browser display and CFML does for server-side processing, VTML does for dialogs and visual tools. VTML is a tag-based language that is used to define and create visual tool elements. These elements include dialogs, fields, help text, file browser and color selectors, and more.

The best part about VTML is that all the language documentation comes with ColdFusion Studio. If you are running ColdFusion Studio 4 or later (you should be), you even have tag editors that fully support VTML.

The Tag
The best way to learn VTML is to use it, so we’ll do just that. is a custom tag that simplifies output redirection. It is a very simple CF4-style tag that lets you wrap any block of HTML or CFML and redirect the output to an email message, a file, or a variable. (If you’ve ever had to gradually construct variable contents or needed to use loops and queries within a tag, you’ll love this one.)

For our discussion, the exact details of how the tag works are unimportant; the tag syntax, however, is very important. can be used in three ways:

  1. This first example redirects all output to an email message:
  2. <CF_OutputRedirect OUTPUT=”email”
                                        TO=”ben@forta.com”
                                        FROM=”ben@forta.com”
                                        SUBJECT=”Redirection”>
    … text, HTML, and CFML goes here
    </CF_OutputRedirect>

  3. This next example redirects all output to a file:
  4. <CF_OutputRedirect OUTPUT=”file”
                                        FILE=”C:USERdump.txt”>
    … text, HTML, and CFML goes here
    </CF_OutputRedirect>

  5. This final example captures all output in a single variable:
  6. <CF_OutputRedirect OUTPUT=”variable”
                                        VARIABLE=”var”>
    … text, HTML, and CFML goes here
    </CF_OutputRedirect>

We’re not going to get into the workings of the tag itself right now. Instead, we’re going to build a tag editor for this new custom tag.

Creating a VTM File
VTM files are plain text files, just like HTML and CFML files. The file we’re going to create is called CF_OUTPUTREDIRECT.VTM, and it needs to be saved under the TagDefs directory (you’ll see a subdirectory called Custom there, which is a great place to save your own custom VTMs).

Make sure you are using an empty file (if Studio used a default template containing text, delete all text before proceeding) and then type the following:

<TAG NAME=”CF_OutputDirect”>
</TAG>

The <TAG> tag is used to define the Tag Editor itself, and all the elements that you provide to build the Tag Editor must be enclosed within <TAG> and </TAG>. The NAME attribute is optional, but it is good practice to use it to specify the actual tag name as I have done above.

Next comes the actual definition, and this is made up of several sections:

  • <EDITORLAYOUT> defines the actual dialog and all of its fields and controls.
  • <ATTRIBUTES> defines the attributes that the Tag Editor must be aware of (so that when you edit a tag all the fields are populated with the existing values).
  • <TAGLAYOUT> defines how text is written back into the editor window (and back into your file).

All of these sections must be present for the Tag Editor to work properly.

Creating the <EDITORLAYOUT> Section
<EDITORLAYOUT> is used to lay out the editor (pretty intuitive, eh?). Start by entering the following text (make sure it is between the <TAG> and </TAG> tags):

<EDITORLAYOUT HEIGHT=”120″ WIDTH=”400″>
</EDITORLAYOUT>

The HEIGHT and WIDTH specify the actual height and width of the dialog you are creating. These attributes are optional, but if you don’t specify them, the dialog could end up looking too big or too small. (Of course, you can right-click on <EDITORLAYOUT> and select Edit Tag to display its tag editor).

Now that we’ve defined the tag editors’s dialog box, we need to populate it. There are two types of items that can go into a layout:

  • Containers — used to create pages or panels within a dialog.
  • Controls — the actual elements within a page or panel.

It is important to note that containers are optional. If you are creating a simple tag editor that uses no panes or panels within it, containers are not needed, and you can use just controls. But our tag editor needs a tabbed dialog with three tabs, one for each of the OUTPUT types. This way the user will be able to select the desired output type and then be prompted for the appropriate data (for an example of this type of dialog, see the tag editors for <CFFILE> or <CFLOOP>). It is also important to note that something (be it a container or a control) must be specified between the <EDITORLAYOUT> tags or you’ll generate an error when you try to display the tag editor.

As our tag editor uses a tabbed dialog, the first thing we need to do is create a container for the tabs. Type the following code between the <EDITORLAYOUT> tags:

<CONTAINER NAME=”MainTabDialog” TYPE=”TabDialog” WIDTH=”MAXIMUM” HEIGHT=”MAXIMUM”>
</CONTAINER>

This creates an empty container as seen in Figure 2. The NAME attribute specifies the name of this container (every container or control should have a unique name). The TYPE specifies that this container is a tabbed dialog (other types include TabPage, which we’ll use in a moment), and the WIDTH and HEIGHT attributes are set to MAXIMUM so that the tabbed dialog fills the entire editor dialog.

Figure 2: Containers are special controls that contain one or more other controls.

Tip: ColdFusion Studio caches VTM files. If you are working on a tag editor and need to keep testing it, you’ll need to empty the cache so that ColdFusion Studio rereads the VTM file. You can do this in ColdFusion Studio 4.0.1 (or later) by pressing Ctrl-Alt-Shift-C. If you are using an earlier version of ColdFusion Studio, you’ll need to quit and restart it (that’s another reason to upgrade).

Now we need to create the actual tabs. Enter the following code in between the <CONTAINER> tags:

<CONTAINER TYPE=”TabPage” NAME=”EMAIL” CAPTION=”EMail”>
</CONTAINER>
<CONTAINER TYPE=”TabPage” NAME=”FILE” CAPTION=”File”>
</CONTAINER>
<CONTAINER TYPE=”TabPage” NAME=”VARIABLE” CAPTION=”Variable”>
</CONTAINER>

The three containers each create a tab as specified by the type. Each tab has a name that should match the value that will be returned if that tab is selected (in our example, it is the OUTPUT attribute’s value). If the names do not match the OUTPUT values, the wrong tab will be displayed when editing code with the tag editor. The CAPTION attribute specifies the caption to be displayed in the tab. Figure 3 shows you what the dialog now looks like.

Figure 3: The TabPage container is used to create tabbed dialogs.

Tip: ColdFusion Studio caches VTM files. If you are working on a tag editor and need to keep testing it, you’ll need to empty the cache so that ColdFusion Studio rereads the VTM file. You can do this in ColdFusion Studio 4.0.1 (or later) by pressing Ctrl-Alt-Shift-C. If you are using an earlier version of ColdFusion Studio, you’ll need to quit and restart it (that’s another reason to upgrade).

Next comes the controls themselves. Each form control is specified using a <CONTROL> tag. There are 16 different types of controls supported allowing you to use everything from text fields to check boxes to color and font selectors to SQL statement builders.
We’ll be using three of these controls in our tag editor.

We’ll start with the FILE tab as that one is simplest. Type the following code between the <CONTAINER> tags for the FILE tab (it’s the second container in the above set of three):

<CONTROL TYPE=”Label” NAME=”lblFile” WIDTH=60 RIGHT=10 DOWN=10 CAPTION=”File:”/>
<CONTROL TYPE=”FileBrowser” NAME=”txtFile” WIDTH=”MAXIMUM” ANCHOR=”lblFile” CORNER=”NE”/>

The first tag creates a label (a caption) as specified by the TYPE attribute. The control is named in the NAME attribute, the actual text is specified in the CAPTION attribute, and the width is specified in the WIDTH attribute (in pixels).

The second control defines a file-browser field (one that lets you enter text or click a file button that is automatically displayed to the right of the field) as specified in the TYPE attribute. The WIDTH is set to MAXIMUM so that the field uses the rest of the available space.

This is where is gets interesting. To manage the placement of controls, relative positioning is used. The first control is placed 10 pixels from the right and 10 pixels down. The second control is positioned next to the first control using the ANCHOR attribute. ANCHOR specifies the name of the control to be used for relative positioning, and ANCHOR=”lblFile” specifies that position is relative to the control named lblFile. The CORNER attribute specifies the direction relative to the ANCHOR. NE (or northeast) means relative to the top right; SW (or southwest) means relative to the bottom left), and so on. In our example, the txtFile field is positioned NE of lblFile. The result is shown in Figure 4.

Figure 4: The Label control is used for captions. FileBrowser is used for file specification and selection.

Note: Notice that <CONTROL> tag end with a slash: /. This is the XML convention when tags have no matching end tags. As there is no </CONTROL> tag used, the <CONTROL> tag must be terminated with a /.

Each of the control types supports a unique set of options. For example, the Label control supports alignment and transparency attributes, while the FileBrowser control supports the optional use of filters and other options. The simplest way to select the options you need is to use the VTM tag editors. Figure 5 shows the tag editor for the FileBrowser control we just created.

Figure 5: You can use VTMs to create VTMs.

The definition for the VARIABLE tab is very similar to the FILE tab, except that it uses a TextBox TYPE to create a text field instead of a file browser. Type the following code between the <CONTAINER> tags for the VARIABLE tab:

<CONTROL TYPE=”Label” NAME=”lblVariable” WIDTH=60 RIGHT=10 DOWN=10 CAPTION=”Variable:”/>
<CONTROL TYPE=”TextBox” NAME=”txtVariable” WIDTH=”MAXIMUM” ANCHOR=”lblVariable” CORNER=”NE”/>

The last tab to look at is the EMAIL tab. Type the following code between the <CONTAINER> tags for the EMAIL tab:

<CONTROL TYPE=”Label” NAME=”lblFrom” WIDTH=60 RIGHT=10 DOWN=10 CAPTION=”From”/>
<CONTROL TYPE=”TextBox” NAME=”txtFrom” WIDTH=”MAXIMUM” ANCHOR=”lblFrom” CORNER=”NE”/>
<CONTROL TYPE=”Label” NAME=”lblTo” WIDTH=60 ANCHOR=”lblFrom” CORNER=”SW” DOWN=10 CAPTION=”To:”/>
<CONTROL TYPE=”TextBox” NAME=”txtTo” WIDTH=”MAXIMUM” ANCHOR=”lblTo” CORNER=”NE”/>
<CONTROL TYPE=”Label” NAME=”lblSubject” WIDTH=60 ANCHOR=”lblTo” CORNER=”SW” DOWN=10 CAPTION=”Subject:”/> <CONTROL TYPE=”TextBox” NAME=”txtSubject” WIDTH=”MAXIMUM” ANCHOR=”lblSubject” CORNER=”NE”/>

This code should be pretty self-explanatory at this point. The EMAIL tab has three fields, so six controls are used – three labels and three fields. All fields are of TYPE TextBox, and all are anchored to their appropriate labels (just like we saw before). But to stack the fields one per line (as seen in Figure 6), the labels need to be anchored, too. The second label, for example, is anchored to the label above it, and the direction is specified as SW (southwest, the bottom left). To space the lines out a bit, DOWN specifies that the control should be placed 10 pixels away.

Figure 6: All controls must be anchored to each other for complete control over alignment and spacing.

And that’s the <EDITORLAYOUT> section.

Creating the <ATTRIBUTES> Section
When you right-click on a tag to display its tag editor, the values currently used are displayed in their appropriate fields ready for editing. This mapping of attribute to field control is specified in the <ATTRIBUTES> section. Type the following text after the </EDITORLAYOUT> tag:

<ATTRIBUTES>
  <ATTRIB NAME=”FILE” CONTROL=”txtFile”/>
  <ATTRIB NAME=”FROM” CONTROL=”txtFrom”/>
  <ATTRIB NAME=”OUTPUT” CONTROL=”MainTabDialog”>
   <ATTRIBOPTION VALUE=”EMAIL”/>
   <ATTRIBOPTION VALUE=”FILE”/>
   <ATTRIBOPTION VALUE=”VARIABLE”/>
  </ATTRIB>
  <ATTRIB NAME=”SUBJECT” CONTROL=”txtSubject”/>
  <ATTRIB NAME=”TO” CONTROL=”txtTo”/>
  <ATTRIB NAME=”VARIABLE” CONTROL=”txtVariable”/>
</ATTRIBUTES>

The entire set of attributes is enclosed within <ATTRIBUTES> and </ATTRIBUTES> tags. Each attribute is specified with an <ATTRIB> tag (again, note the trailing / when </ATTRIB> is not used). <ATTRIB> takes two attributes, the name of the attribute, and the control to associate it with.

So <ATTRIB NAME=”FILE” CONTROL=”txtFile”> instructs the tag editor to take the value passed to the FILE attribute and save it in the txtFile control. The OUTPUT attribute only has three possible values. To restrict the valid values to that known set, the <ATTRIBOPTION> tag is used — one for each value.

When the tag editor is displayed, any existing values will be used. Attributes not present will be ignored, and their controls will be empty, but any attributes present will editable. In addition, the right tab will be selected because the value of the OUTPUT attribute is saved to the MainTabDialog control, which is the control that contains the tab pages.

Creating the <TAGLAYOUT> Section
We’re not done yet. Right now if you were to click Apply, nothing would be written back to the editor window. The final required section is <TAGLAYOUT>. This is used to define the way text gets sent back to the editor when the tag editor’s Apply button is clicked. Here’s the entire code block. Type it in as shown. We’ll analyze it next:

<TAGLAYOUT>
  <WIZIF OPTIONLowerCaseTags EQ ‘true’>
   <WIZSET TAGNAME = ‘cf_outputredirect’>
   <WIZSET FILE = ‘file’>
   <WIZSET FROM = ‘from’>
   <WIZSET OUTPUT = ‘output’>
   <WIZSET SUBJECT = ‘subject’>
   <WIZSET TO = ‘to’>
   <WIZSET VARIABLE = ‘variable’>
  <WIZELSE>
   <WIZSET TAGNAME = ‘CF_OUTPUTREDIRECT’>
   <WIZSET FILE = ‘FILE’>
   <WIZSET FROM = ‘FROM’>
   <WIZSET OUTPUT = ‘OUTPUT’>
   <WIZSET SUBJECT = ‘SUBJECT’>
   <WIZSET TO = ‘TO’>
   <WIZSET VARIABLE = ‘VARIABLE’>
</WIZIF>

<WIZIF OPTIONLinearLayout EQ ‘true’>
  <WIZSET SpacingGap = ‘ ‘ >
<WIZELSE>
  <WIZSET SpacingGap = Chr(13) & Chr(10) & ‘ ‘ >
</WIZIF>

<WIZIF MainTabDialog EQ ‘EMAIL’><$${TAGNAME} $${OUTPUT}=”$${MainTabDialog}”
    $${SpacingGap}$${TO}=”$${txtTo}”$${SpacingGap}$${FROM}=”$${txtFrom}”$${SpacingGap}
    $${SUBJECT}=”$${txtSubject}”></WIZIF>
<WIZIF MainTabDialog EQ ‘FILE’><$${TAGNAME} $${OUTPUT}=”$${MainTabDialog}”
    $${SpacingGap}$${FILE}=”$${txtFile}”></WIZIF>
<WIZIF MainTabDialog EQ ‘VARIABLE’><$${TAGNAME} $${OUTPUT}=”$${MainTabDialog}”
    $${SpacingGap}$${VARIABLE}=”$${txtVariable}”></WIZIF>

</TAGLAYOUT>
The first thing you’ll notice are tags like <WIZIF> and <WIZSET>. These are very similar to ColdFusion’s <CFIF> and <CFSET> tags and work the same way. CFML is processed by ColdFusion, WIZML (Wizard Markup Language — so named because it is used to create the Wizards in Studio and HomeSite) is processed by ColdFusion Studio or HomeSite.

The first block of code in the <TAGLAYOUT> sets a set of sever variables. A checkbox in the ColdFusion Studio Settings options (shown in Figure 7) allows users to specify whether tags should be inserted in upper case or lower case. When a tag editor writes text back to the editor, it should honor this setting (although technically it does not have to), but this does not happen automatically. You have to make it happen. That setting is contained in the OPTIONLowerCaseTags variable, which will be TRUE if tags are to be inserted in lower case and FALSE if they are to be inserted in upper case.

The statement <WIZIF OPTIONLowerCaseTags EQ ‘true’> checks to see if OPTIONLowerCaseTags is TRUE (lower case), and if so, it sets the variables with lower-case values. The <WIZELSE> clause sets the same set of variables to upper case. Once these variables are set, they can be used to render the output, and upper- or lower-case text will be displayed as appropriate.

Figure 7: The Settings dialog “Lowercase all inserted tags” value can be accessed via the OPTIONLowerCaseTags variable.

The next block of code is another conditional statement, this time checking OPTIONLinearLayout. This contains the value of the checkbox at the bottom of every tag editor, which can be used to write out attributes on a single line or on multiple lines. If OPTIONLinearLayout is TRUE, the tag is to be written out on a single line and a space character is used between each attribute. If it is FALSE, a new line character is needed along with enough spaces to line up the attributes properly.

This spacing, too, does not happen automatically. You have to programmatically manage it yourself. The code creates a variable named SpacingGap (it could be named anything you wish) that contains the text to be used between attributes based on the state of that checkbox. Now instead of hard-coding spaces in between attributes, that variable can be used to lay out the output correctly.

The last block of code writes the actual text back to the editor. Depending on the tab selected, different attributes need to be written. For example, the FILE attribute is only written if the FILE tab is selected. It is not used by the EMAIL or VARIABLE tabs. To conditionally write out the correct attributes, a set of
<WIZIF> statements are used. (If this were a simple tag editor (without multiple tabs), we would not have needed three <WIZIF> statements.)

The first statement <WIZIF MainTabDialog EQ ‘EMAIL’> checks to see if the EMAIL tab was selected, and so on.

Within each set of <WIZIF> tags, the appropriate data is written out to the editor. Each block of text starts with a < and ends with a > (the tag delimiters). Next the tag name is written out using the variable $${TAGNAME}. In WIZML, variables are referenced as $${var}. You can think of $${ as the open # in CFML and } as the close #. $${TAGNAME} writes out the text saved in the TAGNAME variable, either upper or lower case as set earlier. Next comes a space, followed by another variable (this time $${OUTPUT}, which contains either the text “OUTPUT” or “output”) and then an equals sign followed by the $${MainTabDialog} within quotes. You’ll remember that MainTabDialog was the name of the tab control created in the <EDITORLAYOUT> section. $${MainTabDialog} contains the value of the selected tab (EMAIL, FILE, or VARIABLE). Each attribute is then separated by $${SpacingGap}, which was set in the <WIZIF> statement above.

And that’s all there is to it.

Conclusion
As you can see, creating your own tag editors is not an overly complicated task. There have been lots of columns and articles written on creating custom tags, and now you know how to polish your tags by creating tag editors for them.

I have only covered the absolute basics of VTM, and there is much more you can do (starting with the 13 other control types and all their possible attributes). A good way to learn VTML is to look at the VTM files associated with standard tags (the HTML and CFML tags that Studio comes with). Pick a tag editor that you use and see how it was created. There is also a complete set of documentation right in the ColdFusion Studio help system.

And there’s even more. In a future article, I’ll show you how to write scripts that run right within the ColdFusion Studio environment. Stay tuned.

Ben Forta is Allaire Corporation’s product evangelist for the ColdFusion product line. Ben has over 15 years of experience in the computer industry and spent 6 years as part of the development team responsible for creating ONTime, one of the most successful calendar and group scheduling products, with over one million users worldwide. Ben is the author of the popular The ColdFusion 4.0 Web Application Construction Kit (now in its third edition) and the more recent Advanced ColdFusion 4.0 Application Development (both published by Que). Ben welcomes your email at ben@forta.com and invites you to visit his own ColdFusion Web site at http://www.forta.com/cf

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles