Related Topics: ColdFusion on Ulitzer

CFDJ: Article

VTML By Example

VTML By Example

In Part 1 of this series (CFDJ, Vol. 3, issue 6), I explained how to easily generate the necessary VTML code for providing Tag Inspector, Tag Help, and Tag Insight features inside CF Studio for your custom tags. (Part 1 is available online at www.sys-con.com/coldfusion/archives/.)

Part 2 focuses on building Tag Editor dialogs using VTML to provide real user interface-based dialogs for your custom tags in CF Studio. If you haven't read Part 1, take a quick look at it before continuing Part 2.

Building Tag Editor Dialogs with VTML
To build Tag Editor dialogs you'll have to leave the guided paths of visual VTML editing and go deep into the hand-coding of VTML. But it's not as complex as it may seem at first glance, so let's begin by analyzing what we already have in code by using a fictional custom tag called <cf_myOwnCustomTag>, which can take the following attributes: <cf_myOwnCustomTag headline="Just a headline" status="Active" titleFont= "Verdana" color="Red">.

Listing 1 contains the completely finished VTML code for our fictional custom tag.

Named by <TAG NAME="CF_MYOWNCUSTOMTAG"></TAG>, the VTML file contains five sections (as outlined in Part 1), while the <ATTRIBUTES> section contains a list of <ATTRIB> tags that represent the attributes the custom tag can take and their types. (Part 1 provides a list of these types.)

The most interesting attribute type is Enumeration, which is a predefined list of certain values an attribute can take:

<ATTRIB NAME="STATUS" TYPE="ENUMERATED">
<ATTRIBOPTION VALUE="Active"/>
<ATTRIBOPTION VALUE="Inactive"/>
<ATTRIBOPTION VALUE="Pending"/> </ATTRIB>
Aside from the value, it's also possible to set a caption for each <ATTRIBOPTION> tag:
<ATTRIB NAME="STATUS" TYPE="ENUMERATED">
<ATTRIBOPTION VALUE="Active" CAPTION="Active connection"/>
<ATTRIBOPTION VALUE="Inactive" CAPTION="Inactive connection"/>
<ATTRIBOPTION VALUE="Pending" CAPTION="Pending request"/>
</ATTRIB>
This <ATTRIBUTES> section of the VTML file is responsible for the Tag Insight feature. The <ATTRIBCATEGORIES> section logically groups attributes into different categories to better organize them in the Tag Inspector. By default, all attributes are in a single category named Misc, but you can group them as you like by simply adding further <ATTRIBGROUP> tags here:
<ATTRIBCATEGORIES>
<ATTRIBGROUP NAME="Misc" ELEMENTS="COLOR,TITLEFONT,HEADLINE,STATUS"/>
</ATTRIBCATEGORIES>
The last section generated by the Tag Definitions Editor is <TAGDESCRIPTION>, which provides your custom tag with a help file (this is an important and handy feature when you're distributing your custom tags). As mentioned in Part 1, by placing the HTML file inside the C:\Program Files\Allaire\ColdFusionStudio\ Extensions\Docs\CFMLTags\directory with a proper name, you can activate the help file in Studio by pressing F1 over your tag.
<TAGDESCRIPTION HELPFILE="../../Docs/CFMLTags/cf_my-OwnCustomTag.htm"/>
To build a tag editing dialog the Tag Definitions Editor needs the code for the user interface and how each control corresponds to an attribute. The <EDITORLAYOUT> and <TAGLAYOUT> sections are responsible for this. Inside the <EDITORLAYOUT> section you'll have to code the user interface by placing controls such as text boxes, drop-down lists, color pickers, and so on, onto the dialog. The <TAGLAYOUT> section describes how the Studio IDE should generate the tag code after you press "OK."

You should be concerned about how the user interface looks. I usually scribble a draft of how the dialog should look and what controls to use that correspond to the attributes. Only after finishing this do I start coding the dialog with VTML.

For our sample tag called <cf_myOwnCustomTag>, we have the following list of attributes: Color (a color value), Titlefont (a font name), Headline (just plain text), and Status (an enumeration of Active, Inactive, and Pending). This list suggests that our Tag Editor dialog should have a color picker, a font picker, a text box, and a drop-down list of the three predefined values for the Status attribute.

The VTML tags you'll need to know for designing the user interface of the dialog are <CONTAINER> and <CONTROL>. As their name suggests, a <CONTAINER> tag (like a panel) can contain <CONTROL> tags corresponding to input controls such as a text box or color picker. Let's start filling the <EDITORLAYOUT> section of our VTML file with a basic dialog for <cf_myOwnCustomTag>:

<EDITORLAYOUT HEIGHT="250" WIDTH="500">
<CONTAINER NAME="Panel1" TYPE="Panel" WIDTH="480" HEIGHT="200" CAPTION="Basic Information">
<CONTROL NAME="lblHeadline" TYPE="label" CAPTION="Headline" DOWN="30" RIGHT="20" WIDTH="60" ALIGN="Right"/>
<CONTROL NAME="txtHeadline" TYPE="TextBox" ANCHOR="lblHeadline" CORNER="NE" WIDTH="350"/>
</CONTAINER>
</EDITORLAYOUT>
This code generates a 500x250 pixel dialog containing one panel (titled Basic Information) that acts as a container for a label control (displaying the text "Headline") and a text-box control named txtHeadline. As the attributes of the <CONTAINER> tag are more or less self-explaining (name, type, width, height, and caption), I'll take a closer look at the <CONTROL> tag. Think of the layout as a relative layout where you can position certain controls with hard-coded coordinates inside a panel (the attributes down and right starting at the upper-left corner of the container panel).

However, you can also position controls relative to each other by setting their anchor attributes to the name of the control to anchor at, as well as specifying the corner (here, NE for northeast, NW for northwest, SE for southeast, and SW for southwest) where the control should be placed, along with the attributes DOWN and RIGHT to assign an offset.

This relative positioning is helpful when you're moving certain controls on the dialog, because you have to move only one control and all anchored controls move too, retaining their alignment and relative position. See the Tag Inspector of the <CONTROL> tag for all possible values of its attributes. By extending the above dialog to show all input controls of our <cf_myOwnCustomTag> sample, which should be a drop-down list, a font chooser, and a color picker, the result looks like that shown in Listing 2 and in Figure 1; see also Listing 1 for its VTML source.

The following types of input controls are possible with VTML:

  • Label
  • TextBox
  • CheckBox
  • RadioGroup
  • DropDown
  • ListBox
  • TextArea
  • FontPicker
  • ColorPicker
  • Image
  • FileBrowser
  • StyleTextBox
  • StyleTextArea
  • SQLTextArea
  • ActiveX
For a complete reference description on how to use these control types, see the ColdFusion Studio help (the section titled "Customizing the Development Environment"). Describing how to use each type would be out of this article's scope; it's meant to be a tutorial, not a reference.

Having noticed that the <CONTROL> tags reside in a <CONTAINER> tag acting as a panel, you're surely interested in what other types of containers are possible:

  • Panel: A general purpose panel container; can contain any controls
  • TabDialog: A tab dialog container capable of containing one or more TabPage containers
  • TabPage: A tab page that can hold a panel; only used inside a TabDialog container
As you see from this list, it's possible to design a tabbed dialog to split and organize many input controls into small chunks accessible via tabs. Listing 3 provides an example of a tabbed dialog.

Making the Dialogs Work
So far you've seen how to design the user interface of a Tag Editor inside the <EDITORLAYOUT> section. Now it's time to make your dialogs work; that is, how to assign certain input controls to certain attributes.

At first the Tag Editor must be aware of what attribute data is currently present in your template to prefill the input controls. For this only a small change must be made in the <ATTRI-BUTES> section: add the attribute CONTROL="theControlName" to each <ATTRIB> tag, while the names of each control should match the names given in the <CONTROL> tags:

<ATTRIB NAME="COLOR" TYPE="COLOR" CONTROL="txtColor/> <ATTRIB NAME="TITLEFONT" TYPE="FONT" CONTROL="txtTitlefont"/> ...
Now, when you're clicking on a <cf_myOwnCustomTag> tag that's holding attributes, you'll see their values successfully being populated into the dialog. But there's still one special situation: imagine that your custom tag is a paired custom tag like <cf_someTag>Some content here</cf_someTag> that's holding content, and you wish to populate this content into your editor dialog. No problem; just assign the content to a control of your dialog using the following special <ATTRIB>-tag: <ATTRIB NAME="$$TAGBODY" CONTROL="txtNameOfControl"/>.

The final step in building a Tag Editor is to assign how the data entered into the dialog's input controls is populated back into the template. To do this you'll have to touch the final <TAGLAYOT> section of our VTML file, which defines a template of how the finished tag (here <cf_myOwnCustomTag>) will be filled with content from the dialog.

Here we'll cover a little bit of WIZML code to define some basic logic of how to generate the tag. For a deeper look into WIZML, I recommend Part 3, which will cover WIZML in greater detail with regard to building custom wizards.

To define what your Tag Editor dialog will output, fill some content inside the <TAGLAYOUT> section. Whatever content there is between <TAGLAYOUT> and its closing counterpart </TAGLAYOUT> will be put back into the template. To output dynamic data depending on what the user has entered in the dialog, you can use WIZML variables, which are written using the following convention: $${name-OfVariable}.

A simple version of our <TAGLAYOUT> section would look like this:

<TAGLAYOUT>
<cf_myOwnCustomTag headline="$${txtHeadline}" status="$${txtStatus}" titleFont="$${txtTitlefont}" color="$${txtColor}">
</TAGLAYOUT>
Try it out and you'll see your Tag Editor dialog working (don't forget to restart CF Studio to let all changes take effect). But you can go even further by using additional logic inside the <TAG-LAYOUT> section.

For example, you can determine whether the user has checked the "Output on single line" checkbox inside the Tag Dialog, and whether the user has set the option of lowercase or uppercase tag code. You can even check for any unknown attributes assigned to the tag code and keep the attributes that are not covered by your dialog untouched.

For these three cases the following special WIZML variables are passed to the dialog:

  • OPTIONLinearLayout: Returns "true" or "false." Specifies whether the tag should be generated with its attributes in a single line or indented vertically.
  • OPTIONLowerCaseTags: Returns "true" or "false." Specifies whether the tag should be generated using lowercase.
  • TAGDATAUnknownAttributes: A string containing all attributes that were contained in the edited tag string, but not recognized by the editor dialog.
You can check for these variables with an easy WIZML tag: just ask if they're true using <WIZIF><WIZELSE></WIZIF>, much like the <CFIF><CFELSE></CFIF> construct that you know (see Listing 1).

Here we simply check for a linear layout and assign either a zero-length string to the variable Spacer or a line break and some spaces. The Spacer is then used behind every attribute, which is output either as lowercase or uppercase depending on the OPTIONLowerCaseTags variable. The template would yield the following Tag Layout:

Linear Layout:

<cf_myOwnCustomTag headline="Just a headline" status="Active" titleFont="Verdana" color="Red">

Nonlinear Layout:

<cf_myOwnCustomTag headline="Just a headline"
status="Active"
titleFont="Verdana"
color="Red">
Finally, you may want to incorporate any unknown attributes of the tag such as <cf_myOwnCustomTag headline="Just a headline" status="Active" titleFont="Verdana" color="Red" someUnknownThing=42 back- groundColor="Blue">. To do this, the editor should check for unknown attributes and retain them instead of losing them during the editing process. All unhandled attributes, if there are any, are available in the variable TAGDATAUnknownAttributes, which should simply be appended at the end of the tag:
<cf_myOwnCustomTag headline="$${txtHeadline}"$${Spacer} status="$${txtStatus}"$${Spacer} titleFont="$${txtTitlefont}"$${Spacer} color="$${txtColor}"<WIZIF TAGDATAUnknownAttributes NEQ "">$${Spacer} $${TAGDATAUnknownAttributes}</WIZIF>>
For a complete listing of the VTML file see Listing 1.

Finally, here's a tip you're surely looking for: instead of restarting CF Studio every time to see your changes, you can press CTRL-SHIFT-ALT-C to reload all VTML files into memory. This saves you a lot of time, and you can blame me for telling you the tip at the end of this article instead of the beginning.

I'd like to sum up that coding VTML is easier than many developers might expect, and doing this little extra work when distributing custom tags pays off in a great deal of added convenience. Macromedia has built well-developed extension possibilities inside the Studio IDE that should be used wherever possible.

More Stories By Christian Schneider

Christian Schneider is an Allaire Certified ColdFusion and Web site developer. He has over four years of intensive experience developing CF-based intranet applications for banks and logistic corporations.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.