WML is a markup language that is based on XML (eXtensible Markup Language). The official WML specification is developed and maintained by the WAP Forum, an industry-wide consortium founded by Nokia, Phone.com, Motorola, and Ericsson. This specification defines the syntax, variables, and elements used in a valid WML file. The actual WML 1.1 Document Type Definition (DTD) is available for those familiar with XML at: https://technical.openmobilealliance.org/Affiliates/WAP.html
A valid WML document must correspond to this DTD or it cannot be processed.
In this tutorial, we’ll present WML basics and an example. This example will demonstrate events and navigation as well as data retrieval from server CGI scripts. Discussion of client-side scripting and state management will be presented in the WMLScript tutorial.
NOTE: We will only discuss features contained in the WML standard. Information on non-standard WML capabilities added by vendors can be obtained by consulting that vendor’s documentation.
Understanding the Wireless Markup Language
WML is based on XML, a markup language that has garnered enormous support due its ability to describe data (HTML, meanwhile, is used to describe the display of data…a big difference). While HTML predefines a “canned” set of tags guaranteed to be understood and displayed in a uniform fashion by a Web browser, XML allows the document creator to define any set of tags he or she wishes to. This set of tags is then grouped into a set of grammar “rules” known as the Document Type Definition, or DTD.
If a phone or other communications device is said to be WAP-capable, this means that it has a piece of software loaded onto it (known as a microbrowser) that fully understands how to handle all entities in the WML 1.1 DTD.
The first statement within an XML document is known as a prolog. While the prolog is optional, it consists of two lines of code: the XML declaration (used to define the XML version) and the document type declaration (a pointer to a file that contains this document’s DTD). A sample prolog is as follows:
<xml version=’1.0’> <!DOCTYPE wml PUBLIC “-//WAPFORUM//DTD WML 1.1//EN”
Following the prolog, every XML document contains a single element that contains all other subelements and entities. Like HTML all elements are bracketed by the<> and</> characters. As an example: <code><element>datadatadata</element></code>. There can only be one document element per document. With WML, the document element is <code><wml></code>; all other elements are contained within it.
The two most common ways to store data within an XML document are elements and attributes. Elements are structured items within the document that are denoted by opening and closing element tags. Elements can also contain sub-elements as well. Attributes, meanwhile, are generally used to describe an element. As an example, consider the following code snippet: <!– This is the Login Card –> <card id=”LoginCard” title=”Login”> Please select your user name. </card>
In the code above, the card element contains the id and title attributes. (On a side note, a comment in WML must appear between the tags.) We will make use of the WML-defined elements and their attributes later as we build our examples.
Valid WML Elements
WML predefines a set of elements that can be combined together to create a WML document. These elements include can be broken down into two groups: the Deck/Card elements and the Event elements.
Anchors, Images, and Timers
Each of these elements is entered into the document using the following syntax:<element> element value </element>
If an element has no data between it (as is often the case with formatting elements such as
<br>), you can save space by entering one tag appended with a
\ character (for instance,
Building Applications With WML
WML was designed for low-bandwidth, small-display devices. As part of this design, the concept of a deck of cards was utilized. A single WML document (i.e. the elements contained within the
<wml> document element) is known as a deck. A single interaction between a user agent and a user is known as a card. The beauty of this design is that multiple screens can be downloaded to the client in a single retrieval. Using WMLScript, user selections or entries can be handled and routed to already loaded cards, thereby eliminating excessive transactions with remote servers. Of course, with limited client capabilities comes another tradeoff. Depending on your client’s memory capabilities, it may be necessary to split multiple cards up into multiple decks to prevent a single deck from becoming too large.
Because multiple cards can be contained within one deck, some mechanism needs to be in place to hold data as the user traverses from card to card. This mechanism is provided via WML variables. Variables can be created and set using several different methods. For instance:
- Using the
<setvar>element as a result of the user executing some task. The
<setvar>element can be used to set a variable’s state within the following elements: go, prev, and refresh. The following element would create a variable named x with a value of 123: <setvar name=”x” value=”123″/>
- Variables are also set through any input element (input, select, option, etc.). A variable is automatically created that corresponds with the name attribute of an input element. For instance, the following element would create a variable named x: <select name=”x” title=”X Value:”>
Although we haven’t discussed WMLScript yet, it is important to note that WML and WMLScript within a document share the same variables.
Creating A WML Deck
In this example, we’ll start by creating a WML deck that allows us to first select a username from a list, enter in a password, then have our selections repeated back to us. This will illustrate the basic handling of user input, events, and variables all within one deck using multiple cards.
<?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=”Login” title=”Login”> <do type=”accept” label=”Password”> <go href=”#Password”/> </do> <p> UserName: <select name=”name” title=”Name:”> <option value=”John Doe”>John Doe</option> <option value=”Paul Smith”>Paul Smith</option> <option value=”Joe Dean”>Joe Dean</option> <option value=”Bill Todd”>Bill Todd</option> </select> </p> </card> <card id=”Password” title=”Password:”> <do type=”accept” label=”Results”> <go href=”#Results”/> </do> <p> Password: <input type=”text” name=”password”/> </p> </card> <card id=”Results” title=”Results:”> <p> You entered:<br/> Name: $(name)<br/> Password: $(password)<br/> </p> </card> </wml>
As you can see, the prolog of this document contains the XML version number to be used as well as the Document Type Definition to be referenced. Following this comes the wml document element (the deck) that contains three cards: Login, Password, and Results. Each of these cards is defined using the element. Because the Login and Password cards also define events, they use the
element to define the event to be triggered. Figure 1 shows the initial card loaded in a test browser.
When the “accept” type of the do element is encountered, it is displayed as an option on the WAP device display (see Figures 2, 3, and 4).
Selecting this option causes the element to be analyzed.
If you are familiar with the anchor tag () in HTML, you know that it specifies an href attribute that tells the browser where to link to if this anchor is selected. The WML element’s “href” attribute works in the same manner. As with HTML, to link to another card in the document, you simply prepend a # symbol before it. For example, to link to the Results card, we define the following element: <go href=”#Results”/>
This Results card makes use of variables by retrieving and displaying the contents of the name and password variables. Recall that variables are substituted into a card or deck by using the following syntax:
Calling A Server Script
Without the ability to perform server transactions, WML would only serve to provide a standardized way to display text on a client. Adding in the ability to dynamically connect to remote servers opens up every WAP device to the world of Internet messaging, enterprise data, and e-commerce. WAP devices interact with these data sources through a WAP gateway as mentioned in our WAP Overview tutorial. This gateway must interface with a carrier such as CDMA, GSM, or GPRS. However, it is possible to install and test gateway products in conjunction with popular Web servers (such as Microsoft Internet Information Server or Apache) on your LAN. This tutorial won’t go into the details of installing and configuring a gateway (see our WAP Tools Comparison tutorial for more information) but to eliminate a very common beginner’s error, we’ll remind you to be sure to add the following MIME types to your Web server: WML text/vnd.wap.wml wml WMLScript text/vnd.wap.wmlscript wmls
Listing 2 – <?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=”Order” title=”Query Inventory”> <p> <select name=”Items” title=”Items”> <option value=”Books”>Books</option> <option value=”Music”>Music</option> <option value=”Video”>Video</option> <option value=”Software”>Software</option> </select> </p> <do type=”accept” label=”Query”> <go href=”http://127.0.0.1/WML/Inventory.asp” method=”post”> <postfield name=”Items” value=”$(Items)”/> </go> </do> </card> </wml>
The server script (shown in Listing 3) examines the input and produces WML output to be displayed on the device.
Listing 3 – Inventory.asp <% Dim Body If Request.Form(“Items”) = “Books” Then Body = “You selected Books!” ElseIf Request.Form(“Items”) = “Video” Then Body = “You selected Video!” ElseIf Request.Form(“Items”) = “Software” Then Body = “You selected Software!” ElseIf Request.Form(“Items”) = “Music” Then Body = “You selected Music!” End If Response.ContentType = “text/vnd.wap.wml”%> <?xml version=’1.0′?> <!DOCTYPE wml PUBLIC “-//WAPFORUM//DTD WML 1.1//EN” “http://www.wapforum.org/DTD/wml_1.1.xml”> <wml> <card> <p> <%Response.write(Body)%> </p> </card> </wml>
Figures 5 and 6 show the Music option being selected and the resultant screen retrieved from the ASP script.
A few things should be mentioned for those wishing to run this example on their local Web server. You must register the proper MIME types with your Web server so that WML content can be properly sent. The two MIME types that should be registered are: .wml text/vnd.wap.wml .wmls text/vnd.wap.wmlscript
If you’d like to use Wireless Bitmap images (the image format supported by WAP), also add: .wbmp image/vnd.wap.wbmp
Finally, I’d like to mention one error I continually received when developing this example using the Nokia WAP Toolkit 1.2. I’ve seen numerous postings on WAP Development boards concerning this error so I thought I’d explain the problem and solution here. Although I registered the MIME types with IIS 4.0, I still received the message “Mime type not supported.” It turns out that even though I was loading the WML source via my local machine’s Web server, the Toolkit was switching over to a file://-based URL since the file was local to my machine. When I then attempted to run the script using href=”Inventory.asp”, I got the error. Switching the href over to http://127.0.0.1/WML/Inventory.asp forced the loading of the script through the Web server which allowed for proper recognition of the WML MIME types.
WML offers software developers an entirely new, exciting platform on which to deploy their applications. With this new platform, however, comes a host of tradeoffs and challenges. A new wrinkle will be added to the design process as things like server round-trips, bandwidth, and display sizes become issues to contend with. While it may take several iterations for developers and vendors to get their product offerings right, there is no doubt that WAP opens the door to a new era in application development and deployment.