Demystifying WMLScript (part 1)

Client-side scripting comes to WML-enabled devices.

Yet Another Acronym

For Web developers, the sudden focus on the new wireless medium is manna from heaven. Not only do they get to rework existing Web sites for the new platform, but they also get to add a brand-new language to their already overcrowded resumes, and throw around yet another acronym at pizza-and-beer gatherings.

However, it's not all fun and games out there. While WML, the language used to WAP-enable Web sites, is a simple and easy-to-learn language, it does come with a bunch of new constructs and entities specific to cellular phones and handheld devices. We've covered most of the important ones in our "Demystifying WML" series at http://www.melonfire.com/community/columns/trog/article.php?id=10, which gets you up and running with the basics of a WML site. And over the next few pages, we're going to teach you how to add interactivity to your WML pages, with the client-side scripting language known as WMLScript.

Technology Marches Onward

If you think back a little, you'll remember how the Web first began with HTML, static pages on which image maps and animated GIFs were considered cutting-edge. And you'll remember how Web users clamoured for more interactivity on those static pages, interactivity that became simpler once dynamic HTML and Javascript became standard accessories for your Internet browser.

If you look at the wireless Web today, you'll see a similar transition taking place. Static WML pages are slowly becoming as passe as static HTML pages, and users are looking for more interactivity...preferably with a minimal performance hit. WMLScript promises to bring Javascript-like capabilities and power to WML developers, by providing them with a powerful tool for client-side scripting.

WMLScript is based on ECMAScript, which is the standard for all client-side scripting languages. The ECMAScript standard, created by the European Computer Manufacturers Association (ECMA), is adhered to by most current client-side languages in use on the Web, including JavaScript and VBScript. Since WMLScript is currently the only scripting language that can work on WAP-enabled wireless devices, it has been developed keeping the ECMA standards in mind; despite this, however, it still does not meet all the standards laid down by ECMA due to inherent constraints in the medium.

The Rationale For WMLScript

WMLScript also offers substantial gains to users, developers and service providers. In the current scenario, where bandwidth is limited, it is impractical to connect to the server for simple tasks like form field validation or basic mathematical calculation. It is far more practical to transfer the processing of simple tasks to the client device, thereby reducing server load and bandwidth usage and also speeding up the processing of simple tasks. Thus, by transferring the load from the server to the client, WMLScript offers many of the same advantages that Javascript did when it was first introduced:

  • Users pay a lower end cost, since there is less traffic going back and forth between the server and their wireless device.

  • Service providers benefit from reduced load on their systems.

  • Developers can speed up the execution of simple tasks by running them on the client machine, which will process them faster.

Opponents of this methodology will trumpet the fact that the current generation of mobile devices is not equipped for this kind of client-side processing, due to a relatively less powerful microprocessor and a limited amount of memory. To some extent, this argument holds good; however, it will slowly fade as newer, more powerful devices make their appearance. In fact, future iterations of this language will have the capability to access the device's in-built functionality - phone book, to-do list, et al - and thereby offer much greater flexibility to developers and coders.

The Tools

Before you get started with WMLScript, though, you need to be aware of one important caveat. Most of the cellphones currently available lack support for WMLScript, which means that you'll be limited to a simulator for all your programming and testing. As cellphones grow more powerful, expect WMLScript support to become available in the WAP micro-browser itself - Nokia and Ericsson are already working on this.

The simulator we'll be using throughout this tutorial is the Nokia WAP Toolkit 2.0, which is available from the Nokia Web site at http://www.nokia.com. The WAP Toolkit also requires the Java Runtime Environment, which you can get from Sun's Web site at http://java.sun.com

The Nokia Toolkit can be used in one of two different modes. The first is the BluePrint device, an emulator that supports the WAP 1.2 standard, while the other is a simulator for the Nokia 7110 mobile phone, which was one of the first WAP-enabled mobile devices to hit the market. You can use either device to test your WMLScript pages; however, we've found that the BluePrint emulator is significantly faster than the Nokia 7110 emulator.

The Toolkit comes with a bunch of handy debugging capabilities, all accessible via tabs at the bottom. The two most useful ones are the "messages" dialog, which tracks debug messages as your scripts are processed, and the "variables" dialog, which shows you the current values of all your WMLScript variables.

We'll also be assuming that you're familiar with basic programming concepts like variables and operators, and that you have read and understood our "Demystifying WML" tutorial.

Now that you have tools in place to test your code, it's time to get started with some programming.

Hello!

Here's a simple example that demonstrates how WMLScript can ask for user input and render it on the display, all via client-side variables.

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>
<card id="Hello" title="Hello">
<p>
    What is your name?
    <input format="*M" name="name" title="Name"/>
    <br/>
    Hi, $(name)
</p>
</card>
</wml>

Here's what it looks like:

Playing With Numbers

Our second example is also pretty simple - ask the user to enter two numbers and then return the sum. Here's the WML deck itself:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>
<card id="question" title="Addition">
<p>
        Gimme a number:
        <input format="N*" name="num1" title="First number"/>
        <br/>
        Now, gimme another:
        <input format="N*" name="num2" title="Second number"/>
        <br/>
        <do type="accept" label="Add Them">
        <go href="addition.wmls#addme($(num1),$(num2))"/>
        </do>
    </p>
</card>

<card id="answer" title="Addition Result">
<p>
    The sum of the numbers $(num1) and $(num2) is $(sum)
</p>
</card>

</wml>

As you can see, the page above sets up fields for the user to enter two numbers into the WML equivalent of a form. There's also a second card in the deck, which we'll be using to display the results of the addition.

Once the numbers have been entered, the next step is to add them - which is where the

<go href="addition.wmls#addme($(num1),$(num2))"/>

comes in; it specifies the name of the function - addme() - to be used for the addition, as well as the name of the WMLScript file - "addition.wmls" - which contains the function definition.

This is where things start to get interesting. Unlike other client-side scripting languages, WMLScript cannot be embedded within the WML page itself; it needs to be placed in an external file with the extension ".wmls", and the WML server needs to be configured to serve this type of file correctly (more information on how to do this is available in the "Demystifying WML" tutorial).

Let's take a look at the "addition.wmls" file, which contains the addme() function:

// function to add two numbers

extern function addme(number1, number2)
{

    // variable to store the result of addition
    var sumIs;

    // perform addition
    sumIs = number1 + number2;

    // use the WMLBrowser browser library to set up WML variables
    // and refresh the page
    WMLBrowser.setVar("sum",sumIs);
    WMLBrowser.go("addition.wml#answer");

}

The example above contains a user-defined function called addme(), which accepts three parameters: two numbers to be added and a variable to store the result in. Once the numbers have been added, they are stored in the variable "sumIs".

Next, two in-built WML browser libraries are used to first set the value of the variable "sum" to the number contained in "sumIs", and then to load the result card from the deck. We'll be examining these functions in more detail in the second part of this series - for the moment, all you need to remember is that they're used to load a new card from the deck with appropriate variable-value pairs.

The Rules Of The Game

Now that you've understood the manner in which the language is structured, it's time to take a closer look at the individual components of the language, together with some of the rules governing it. If you're familiar with JavaScript, these should come as no surprise.

  1. All WMLScript statements should end with a semi-colon. For example,
sumIs = number1 + number2;

var x;
  1. All variable and function names are case-sensitive. For example, in WMLScript, "sumIs" and "SumIs" are two different variables.

  2. Whitespace is not considered when processing WMLScript statements. For example,

    var sumIs;

    sumIs =     number1 +   number2;

is the same as

    var sumIs; sumIs=number1+number2;

Obviously, it's good programming practice to use whitespace and newline characters in as efficient a manner as possible, for easy readability of your code.

  1. Comments can be incorporated within WMLScript code via the same conventions used in JavaScript. Single-line comments must be preceded by the // characters, while multi-line comments must be enclosed within a // comment block. For example,
// this is a single-line comment

and

/* This is
    a multi-line
    comment */

Storing Data...

As with other programming language, there are several types of variables that can be used in WMLScript.

Integer - whole number

Float - decimal number

String - character data

Boolean - true or false

Invalid - a special variable type.

The "var" keyword is used to define a new variable, like this:

var sumIs;

WMLScript does not allow you to specify the variable type at the time of defining it. A variable can thus hold any type of data, and its type is defined by the data it contains.

Variables must be defined before they can be used. You can initialize a variable at the time of defining it, like this

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>
<card id="Hello" title="Hello">
<p>
    What is your name?
    <input format="*M" name="name" title="Name"/>
    <br/>
    Hi, $(name)
</p>
</card>
</wml>

or not, in which case it is initialized to an empty string value.

Variable names in WMLScript cannot begin with a digit, but can begin with an underscore or alphabetic character. Obviously, reserved WMLScript keywords cannot be used as variable names.

...And Operating On It

WMLScript also offers a bunch of different operators for use in your scripts, of which the most widely used is the assignment operator, represented by the = symbol. The assignment operator is used to assign a value to a variable, and can also be used to initialize variables when they are first defined. For example, the statement

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>
<card id="Hello" title="Hello">
<p>
    What is your name?
    <input format="*M" name="name" title="Name"/>
    <br/>
    Hi, $(name)
</p>
</card>
</wml>

assigns the string "marks the spot" to the variable named "x".

WMLScript supports all the common mathematical operators - addition, subtraction, multiplication, division and modulus. WMLScript also comes with a "div" operator, which can be used to return the integer part of an expression, ignoring the fractional part. Consider the following example:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>
<card id="Hello" title="Hello">
<p>
    What is your name?
    <input format="*M" name="name" title="Name"/>
    <br/>
    Hi, $(name)
</p>
</card>
</wml>

The basis of interactivity is decision-making, and WMLScript supports numerous comparison operators to help in building conditional statements. These include the "equal-to" operator (==), "not-equal-to" operator (!=), "greater-than" (>) and "less-than" (<) operators. Oh yes…and let's not forget the "greater-than-or-equal-to" (>=) and "less-than-or-equal-to" (<=) operators too.

If Only...

The simplest form of conditional statement available in WMLScript is the "if" statement, which looks something like this:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>
<card id="Hello" title="Hello">
<p>
    What is your name?
    <input format="*M" name="name" title="Name"/>
    <br/>
    Hi, $(name)
</p>
</card>
</wml>

The "condition" here refers to a conditional expression, which evaluates to either true or false. If the statement evaluates to true, all script code within the curly braces is executed; if not, the code within the curly braces is skipped and the lines following the "if" construct are executed.

Here's a quick example:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>
<card id="Hello" title="Hello">
<p>
    What is your name?
    <input format="*M" name="name" title="Name"/>
    <br/>
    Hi, $(name)
</p>
</card>
</wml>

In addition to this, WMLScript also supports the "if-else" construct, which allows for multiple decision branches.

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>
<card id="Hello" title="Hello">
<p>
    What is your name?
    <input format="*M" name="name" title="Name"/>
    <br/>
    Hi, $(name)
</p>
</card>
</wml>

Calculating The Odds

The next example will illustrate how conditional operators can be used in WMLScript with a simple calculator application for a WMLScript-enabled mobile device. Here's the initial deck, which contains two cards: one for the selection screen and the other for the result screen.

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>
<card id="Hello" title="Hello">
<p>
    What is your name?
    <input format="*M" name="name" title="Name"/>
    <br/>
    Hi, $(name)
</p>
</card>
</wml>

As you can see, once the user has entered two numbers and selected the operation to be performed, the calculate() function is invoked from the script file "calc.wmls". Here it is:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>
<card id="Hello" title="Hello">
<p>
    What is your name?
    <input format="*M" name="name" title="Name"/>
    <br/>
    Hi, $(name)
</p>
</card>
</wml>

Note the various "if-else" statements used to decide the type of operation, as also the manner in which the result is passed to the second card in the deck.

Naturally, there's a lot more to WMLScript than just this - and in the concluding part of this series, we'll be looking at WMLScript's loops, library functions, and a few other simple client-side applications. Make sure you don't miss it!

This article was first published on05 Oct 2000.