HomeSite Help

VTML Tips and Techniques: General

 

We're moving!

This whole site is being moved to a shiny new server - as are all my sites, in fact. Apologies for the bumpy road ahead, but at the end of that road things will become fast and smooth.

Once the site at the new server is ready, this message will automatically disappear!

Meanwhile, you can see how the move is progressing at the status page.

 
   Home | VTML section | HTML section
On this page:
Comments
Variable names
Two Lists
Was that value changed?
Preselecting a tab
Contributions!
 
 

Comments

While using comments are good coding practice, and generally you can use comments in (or between) the different sections of a VTM file, there is one place a comment cannot occur: if you put a comment as the very first (non-blank) line in a VTM file, HomeSite will first throw up a message box with the text:

"Could not retrieve editor definition from file: ..."

(with full file path); when you then press OK (no other choice) this is followed by Homesite's "Huh!?" error message (an error message window without any message), meaning it can't layout the editor window.

If you do want to put in a comment about the whole editor file, put it just after the TAG statement. Normal HTML formatting for comments applies.  to menu VTML Tips and Techniques


 

Variable names

I haven't found any formal description of variables and how they're used in VTML but it's useful to sum up a few facts I determined largely by trial and error (and some systematic testing):

  • A variable name can consist of letters, digits, dashes (-) and dots (.).
  • The name has to begin with a letter.
    Examples: correct: A8  a--  a.b  a1b2c3  file.  wrong: 8a  -c  .dot 
  • Variable names are case-insensitive.
  • I have not come across a maximum length; there probably is one, but whatever it is it's quite sufficient for creating long, meaningful variable names.
  • All rules for variable names equally apply to names for controls in EDITORLAYOUT (since at least input controls can be used as variables in the TAGLAYOUT section).
  • When the parser encounters something that is not a letter, digit, dash or dot, it will either interpret it as literal text or as an operator (when it's part of an expression).
  • Anything that cannot be part of a variable name is seen as a separator.
  • To output the value of a variable, you put $$ in front of it.
  • To output the result of an expression, you surround the expression with { } and put $$ in front of it.
  • The { } around an expression usefully serve as delimiters: if you need to output the value of a variable immediately followed by literal text starting with one of the characters that can be part of a variable name, the parser has no way to determine where the variable name stops and where the literal text starts; just turn the variable into an expression by enclosing it in { }.
    (Note: this is the coding style seen for outputting all variables in the tag editors that come with HomeSite but generally it's not necessary to surround variable names with braces; it just makes the code unnecessary large.
    In my tag editors I don't follow this coding style but only use braces to surround expressions and when I really can't avoid it to serve as delimiters.)
  • While the parser is really picky (what else?) when outputting variables or expressions or using expressions as the source in an assignment, curiously in WIZSET you can do almost anything to indicate the target of the assignment: if it isn't a correct variable name it's simply ignored (no error message!); the surprise comes when you try to use the result of that assignment.

A few examples; all preceded by the following set of assignments:

<WIZSET a = 1>
<WIZSET a/8 = 8>
<WIZSET a_8 = 5>
	

These examples nicely illustrate how the parser behaves with respect to variable names and expressions; they also illustrate why a consistent coding style putting spaces around operators in expressions is important for not confusing yourself.

  1. $$a_8

    Result: "1_8"
    Explanation: the assignment to "a_8" is ignored; variable "a" has the value 1. During output, "_" cannot be part of a variable name so what precedes it is seen as the variable "a" (evaluated to 1) and the rest is just output as literal text.

  2. $${a_8}

    Result: Error: Unexpected token "_" found while parsing expression
    Explanation: this indicates the assignment to "a_8" really is ignored; even when enclosed in braces it is not seen as a variable name. The parser now tries to evaluate the expression and unlike in the previous example where the "_" could be seen as literal text, it can't in an expression; "a" is still recognized as an existing variable but "_" is not any kind of operator.

  3. $$a/8

    Result: "1/8"
    Explanation: the assignment to "a/8" is ignored; variable "a" has the value 1. During output, "/" cannot be part of a variable name so what precedes it is seen as the variable "a" (evaluated to 1) and the rest is just output as literal text.

  4. $${a/8}

    Result: "0.125"
    Explanation: the assignment to "a/8" is ignored; variable "a" has the value 1. Now the expression between braces is evaluated before output: 1 divided by 8 equals 0.125.

  5. <WIZSET B = A/8>$$b

    Result: "0.125"
    Explanation: the assignment to "a/8" is ignored; variable "A" has the value 1. The assignment "B = A/8" then has the expression "A/8" evaluated and this is assigned to "B". "$$b" outputs the result.  to menu VTML Tips and Techniques

 
 

Two Lists

The Editorlayout section already explains a couple of techniques for the DropDown control which can be used to let the user choose one of a set of values.

But what if HTML defines a fixed set of possible values for an attribute but a particular browser allows a superset of that list? The answer is to use two DropDown controls, both not editable (and both with and empty entry at the top if the attribute is not required). The technique involves three sections: Editorlayout, Attributes and Taglayout.

Let's take the ALIGN attribute of the IMG tag as an example. HTML 4.0 allows five different values: top, middle, bottom, left and right. But Netscape, MS Internet Explorer and WebTV have a few more possibilities: absbottom, absmiddle, baseline and texttop (though it's unclear which browser version actually supports what).

First of all, as even the original VTML documentation mentions, you can use the ATTRIBUTES section to assign a tag attribute (when editing the tag) to two (or more) controls. So on the main tab of my Img.vtm tag editor I have a DropDown with just the standard HTML values (plus empty):

 
  
<CONTROL TYPE="DropDown" NAME="dropAlign" WIDTH=100 ANCHOR="lblAlign" CORNER="NE">
    <ITEM VALUE=""            CAPTION="">
    <ITEM VALUE="left"        CAPTION="left">
    <ITEM VALUE="right"       CAPTION="right">
    <ITEM VALUE="top"         CAPTION="top">
    <ITEM VALUE="middle"      CAPTION="middle">
    <ITEM VALUE="bottom"      CAPTION="bottom">
</CONTROL>
	
  

Then on the Browser-specific tab I have another DropDown, with the extended set:

 
  
<CONTROL TYPE="DropDown" NAME="dropAlignOther" WIDTH=100 ANCHOR="lblAlign" CORNER="NE">
    <ITEM VALUE=""            CAPTION="">
    <ITEM VALUE="left"        CAPTION="left">
    <ITEM VALUE="right"       CAPTION="right">
    <ITEM VALUE="top"         CAPTION="top">
    <ITEM VALUE="texttop"     CAPTION="texttop">
    <ITEM VALUE="middle"      CAPTION="middle">
    <ITEM VALUE="absmiddle"   CAPTION="absmiddle">
    <ITEM VALUE="baseline"    CAPTION="baseline">
    <ITEM VALUE="bottom"      CAPTION="bottom">
    <ITEM VALUE="absbottom"   CAPTION="absbottom">
</CONTROL>
	
  

Note that the controls have different names, but in the ATTRIBUTES section I assign the attribute ALIGN to both these controls:

 
  
<ATTRIB NAME="ALIGN"    CONTROL="dropAlign">
...
<ATTRIB NAME="ALIGN"    CONTROL="dropAlignOther">
	
  

Now when editing an exiting tag, the fact that the DropDowns are not editable will make sure that a value not occuring in the list is not picked up; if the user had typed a completely different value, both DropDowns would show the empty value. If the tag had a browser-specific attribute value, the DropDown on the Browser-specific tab would show that value, but the DropDown on the main tab would still show the empty value. And if the tag had an attribute value that occurs in both lists, both DropDowns would show that value.

(Note: currently there is no way for a VTM to edit an existing IMG tag since this editor is built-in. But I'm hoping fervently the next version of HomeSite will give us the option to choose between the built-in editor and our own version for editing, giving us much more flexibility and a better way to keep up with HTML developments.)

When writing the new (or edited) tag, the TAGLAYOUT looks at the values in both DropDowns and takes a decision: If a browser-specific value has been chosen, that takes precedence; is that is not the case but both are non-blank, the HTML DropDown on the main TabPage takes precedence; and if the latter is empty but the browser-specific one is not, the browser-specific one is used:

 
  
<WIZIF Find(dropAlignOther, 'abs') OR Find(dropAlignOther, 'base') OR Find(dropAlignOther, 'text')>
    <WIZSET Align = dropAlignOther>
<WIZELSEIF dropAlign NEQ ''>
    <WIZSET Align = dropAlign>
<WIZELSEIF dropAlignOther NEQ ''>
    <WIZSET Align = dropAlignOther>
</WIZIF>
	
  

So if at least one of the DropDowns has a value, the variable Align will be assigned a value; if both are empty, Align will remain empty as well. This is used to decide whether or not to write the attribute:

 
  
<WIZIF Align NEQ ''>$$SpacingGap$${DefaultCase('ALIGN')}=$$Align</WIZIF>
	
  

This way, two non-editable DropDowns together with assignment to two controls in the ATTRIBUTES section and the decision-making in the TAGLAYOUT section take care of two variants of the same attribute.  to menu VTML Tips and Techniques


 

Was that value
changed?

Here's another technique that involves several sections, in this case EDITORLAYOUT, ATTRIBUTES and TAGLAYOUT. This is about how to determine whether an attribute value was changed (or how to hide a control).

When working on the tab for a Conditional loop in the WIZLOOP tag editor (part of my package of VTML Tag Definitions) I realized that in the TAGLAYOUT section I would need to make a decision to give precedence to the field with the whole condition in string form or the fields in the condition builder panel. It's easy enough to just always give precedence to the string field. But that's not very user-friendly: when I'm editing a condition I could either just edit the string field or decide to use the condition builder to rebuild the condition of build a new one; but in the latter case I'd have to go back to clear the string field or I'd just get my old condition back.

So... wouldn't it be nice to give precedence to the string field only if it's changed when both areas contain input? To do that, I'd need to remember the value of the string field before the user touched it. What I found after a lot of puzzling and testing could be either called a technique or a dirty trick - depending on your preference. I'm certainly violating some rules - but it doesn't seem to break anything, so let's just call it a technique for now. ;-)

To determine whether an attribute has changed, I'll need to compare the current value with the previous value, so I need two controls: one to "remember" the old one, and one the user can change. My first approach was to build on the technique described for Display-only controls: use a label to hold the current value, so that could be compared with the string from the textbox used for input. Nice idea only it didn't work. I found out that while a label can be used to display a value, it cannot be used to store a value. When using the value of a label in an expression the result is always an empty string. In other words: a label control is write-only.

Well, I know I can query the value of a textbox, so I'll need to use a second textbox - but prevent the user from touching it: only the "real" should be editable. So I could make the comparison textbox non-editable. But now I still have a user interface problem: having two textboxes on the screen with the same value can be really confusing - even if only one is editable.

So I wanted to hide the memory textbox. Alas, there's no HIDE attribute for controls in VTML. But guess what? I found I can hide a control all the same. And this is where it gets a little dirty. Here's a code fragment from the EDITORLAYOUT section of the WIZLOOP editor:

 
  
<CONTAINER TYPE="Panel" NAME="pnlCondition" CAPTION=" Condition " WIDTH="MAXIMUM" HEIGHT=55 HORIZRESIZE="BODY" MAXWIDTHPADDING=10 RIGHT=10 DOWN=5>
    <CONTROL TYPE="TextBox" NAME="txtCondition" WIDTH="MAXIMUM" RIGHT=20 DOWN=20>
    <CONTROL TYPE="Image" WIDTH=12 HEIGHT=12 ANCHOR="txtCondition" CORNER="NW" RIGHT=-15 FILEPATH="Images/Asterisk_g.bmp" TRANSPARENT="Yes">

    <!-- Use TextBox control outside of display area to save current value! -->
    <CONTROL TYPE="TextBox" NAME="saveCondition" WIDTH=1 HEIGHT=1 ANCHOR="pnlCondition" CORNER="NW" RIGHT=-20 DOWN=-20>
</CONTAINER>
	
  

Note what I'm doing to hide the "saveCondition" textbox: First of all, I'm giving a hight and width of 1 so it'll be really small (it can still hold a value). Then I'm using the NW corner of the panel the textbox is defined inside of, and positioning the textbox 20 pixels up and to the left of that corner: in other words, it ends up outside of the panel it's supposed to be in - and this effectively hides the field.

So now that hiding the save field is taken care of, the rest is rather straightforward. In the ATTRIBUTES section, the current condition is assigned both to the input field and to the save field:

 
  
<!-- Conditional loop -->
<ATTRIB NAME="CONDITION"    CONTROL="txtCondition">
<ATTRIB NAME="CONDITION"    CONTROL="saveCondition"><!-- save state before editing -->
	
  

And finally here's the decision-making bit in the TAGLAYOUT section:

 
  
<WIZELSEIF loopType EQ 'ConditionalLoop'>
    <WIZIF (txtCondition NEQ '') AND (txtCondition NEQ saveCondition)>
        <WIZIF 1> $${DefaultCase('CONDITION')} = '$$txtCondition'</WIZIF>
    <WIZELSE>
        ... (building condition from the condition builder fields)
    </WIZIF>
...
	
  

Like so many techniques: once you know how to do it, it's really simple.  to menu VTML Tips and Techniques


 

Preselecting
a tab

While working on a better interface for the Tag Chooser, I hit on an idea: when you edit a tag and the tag editor has TabPages corresponding to different types of that tag, the appropriate tab will be selected automatically. Now wouldn't it be nice if you could have the Tag Chooser call up such a tag editor with a particular tab preselected? Well, if the tab corresponds to an attribute, you can!

Although the main focus of the technique is the Tag Chooser (MarkUpTags.vtm), it also involves the EDITORLAYOUT and ATTRIBUTES section of a tag editor, so that's why you find it here.

The following bit of code lets you choose my WIZLOOP tag editor with either the Index, Conditional or List loop tab preselected:

 
  
<E CAPTION="WIZLOOP Index"      VALUE='<WIZLOOP TYPE="IndexLoop"'       HELPFILE='Docs/VTMLTags/MKwizloop.html'>
<E CAPTION="WIZLOOP Condition"  VALUE='<WIZLOOP TYPE="ConditionalLoop"' HELPFILE='Docs/VTMLTags/MKwizloop.html'>
<E CAPTION="WIZLOOP List"       VALUE='<WIZLOOP TYPE="ListLoop"'        HELPFILE='Docs/VTMLTags/MKwizloop.html'>
	
  

What's that? WIZLOOP does not even have a TYPE attribute. Well, if it had, this would be all there is to it. (I'm using the same technique for Input.vtm to preselect a tab for a particular form element). For WIZLOOP it requires an extra bit of code in the ATTRIBUTES section of the tag editor to fool it into thinking there actually is a TYPE attribute:

 
  
<ATTRIB NAME="TYPE"  CONTROL="loopType">
<!-- allows tab selection from the tag chooser dialog -->
	
  

The name of the control in this ATTRIB tag corresponds to the TabDialog which is called "loopType":

 
  
<CONTAINER TYPE="TabDialog" NAME="loopType" ...
	
  

and the names of the TabPages within that TabDialog correspond to the TYPE attributes mentioned in the VALUE attributes of the <E> tags in MarkUpTags.vtm:

 
  
<CONTAINER TYPE="TabPage" NAME="IndexLoop" CAPTION="Index Loop">
<CONTAINER TYPE="TabPage" NAME="ConditionalLoop" CAPTION="Conditional Loop">
<CONTAINER TYPE="TabPage" NAME="ListLoop" CAPTION="List Loop">
  

It requires careful construction but it works nicely. In this case, the (dummy) entry in in the ATTRIBUTES section is the key that ties the Tag Chooser to the TabDialog of the tag editor.

It's a pity there is no way to call this mechanism when selecting a tag editor from the tool bar: there you have to specify the file name of the tag editor instead of letting HomeSite find it itself from the tag name. I tried passing a parameter to the tag editor but could find no way to do that. Now wouldn't it be nice to be able to pass a parameter to a tag editor (from the toolbar) or have a different mechanism to call one (like it works in the Tag Chooser)?  to menu VTML Tips and Techniques


 

Contributions!

Do you have any VTML Tips or Techniques to share? If it's for the General section, use the following email link, otherwise go to the page corresponding to the section it's about and use the Contributions! mail link from there, so your mail will have the correct subject.

Please explain why it's such a good tip, and illustrate with example code where appropriate. Also let me know whether you want you email address mentioned here, or only your name.

Send your contribution to: mail VTML Tips and Techniques Contributions

The VTML Tips and Techniques sections are:

 to menu VTML Tips and Techniques