YOUR FEEDBACK
Ross Cooney wrote: Buying servers is capital intensive...and impossible for startups. Buying capaci...
Cloud Computing Conference
November 19-21 San Jose, CA
Register Today and SAVE !..


2008 East
DIAMOND SPONSOR:
Data Direct
Frontiers in Data Access: The Coming Wave in Data Services
PLATINUM SPONSORS:
Red Hat
The Opening of Virtualization
Intel
Virtualization – Path to Predictive Enterprise
Green Hills
IT Security in a Hostile World
JBoss / freedom oss
Practical SOA Approach
GOLD SPONSORS:
Software AG
The Art & Science of SOA: How Governance Enables Adoption
PlateSpin
Effective Planning for Virtual Infrastructure Growth
Fujitsu
Automated Business Process Discovery & Virtualization Service
Ceedo
Workspace Virtualization
Click For 2007 West
Event Webcasts

2008 East
PLATINUM SPONSORS:
Appcelerator
Think Fast: Accelerate AJAX Development with Appcelerator
GOLD SPONSORS:
DreamFace Interactive
The Ultimate Framework for Creating Personalized Web 2.0 Mashups
ICEsoft
AJAX and Social Computing for the Enterprise
Kaazing
Enterprise Comet: Real–Time, Real–Time, or Real–Time Web 2.0?
Nexaweb
Now Playing: Desktop Apps in the Browser!
Sun
jMaki as an AJAX Mashup Framework
POWER PANELS:
The Business Value
of RIAs
What Lies Beyond AJAX?
KEYNOTES:
Douglas Crockford
Can We Fix the Web?
Anthony Franco
2008: The Year of the RIA
Click For 2007 Event Webcasts
SYS-CON.TV
TOP COLDFUSION LINKS


Developing a WAP Based E-mail Interface
Developing a WAP Based E-mail Interface

This article is about developing an application for wireless devices with WAP support. For this I've chosen to implement a WAP-based e-mail client.

On the Web, using HTML, this is quickly done with ColdFusion. This should also be true for WAP, I thought. Whether or not it turns out to be true...well, just read on.

Okay, it did turn out to be easy, since CFDJ has published several articles about the design and pitfalls of WAP development in the last few months. I strongly suggest that you also take a look at the two-part article "Developing Wireless Apps with ColdFusion" by Charlie Arehart (CFDJ, Vol. 2, issues 8, 9).

To start developing a real-world WAP application, you need to know the basics of WAP and WML, such as knowing that a WML "page" is called a "card," and a "deck" is a collection of "cards" being transferred all at once. You'll also need intermediate skills in ColdFusion, especially an understanding of the <CFPOP> and <CFMAIL> tags we're going to use in this application. But if you're a novice, don't be discouraged if these terms mean nothing to you. You'll get to know them all during the course of this article.

I recommend that you download and install the mobile phone simulator UP.SDK from www.openwave.com (formerly phone.com) on your PC (see the referenced Arehart article for more details) so you can test this application without a WAP-capable device.

Take a look at Figure 1, which diagrams the application's flow. To better understand the diagram, I've provided a number of screenshots (see Figures 2-6). As I explain the flow in the next paragraphs, you can directly link the screenshots to the different states in the UML diagram.

As you can see in Figure 1, after providing the login information, the mobile user can either check for mail or compose new mail (see also Figures 2 and 3).

When checking for new mail, the CF server uses the provided login information (stored into the session) to access the user's mail account via <CFPOP> and displays the result as a listing of all mail headers (see Figure 4). After selecting a message, the details are shown in a separate card (see Figure 5), where the user can decide either to open the mail or to delete it from the server. After opening an e-mail, the user can read it and then either return to the inbox for more mail, delete it from the server, or send a reply (see Figure 6).

When you look at the source code on the Web (at www.sys-con.com/coldfusion/sourcec.cfm), you'll see that I first coded this application in HTML for the Web browser to be sure of its functionality, then modified the HTML prototype into a WAP/WML solution for wireless devices. I originally thought I'd better not do this since some concepts of application flow that work well in HTML would certainly not work in WML and vice versa, but after I finished the prototype, the change to WML was easier than I expected.

Naturally, this kind of prototyping only works when you're thinking of WML all the time and concentrating on the flow of your mobile phone application. But with this in mind, you can quickly ensure that your application's features are working, since testing and debugging in an HTML-based Web browser is much easier than with WML on WAP devices (you all know how to debug in the HTML/Web browser environment, but I'm sure not all of you have a good way to track errors using a mobile phone).

Once the HTML prototype was completed, I felt a little sad about dropping it after having ported it on WML, so I had the templates check for WAP devices or HTML-capable browsers to decide which version to send to the client. This was done with just a few lines of simple code:

<!--- Test of WAP-Devices (Auto-Detect) --->
<cfif CGI.HTTP_ACCEPT CONTAINS "text/vnd.wap.wml">
<cfset isWap = true>
<cfelse>
<cfset isWap = false>
</cfif>
Here we check the CGI variable CGI.HTTP_ACCEPT for the MIME types the client browser accepts. If the client accepts "text/vnd.wap.wml", you can be sure it's a mobile WAP device; if it doesn't, most likely it's the usual HTML-capable Web browser. Having placed this simple check inside the Application.cfm file (see Listing 1), we can tell whether the user is "surfing" with a mobile WAP phone or a standard Web browser. As you'll see when you look at the other code listings, most pages check for this flag at the beginning and serve different content depending on whether it's WML or HTML. For more complex applications that behave differently when accessed via WAP than they do via a conventional Web browser, you might think of writing two sets of templates (at least for presenting the user interface) instead of just checking within each template. For simpler applications, such as the example in this article, the first method - deciding within the templates - is just fine.

Design Considerations for WML
A primary concept of WML design you need to understand is that WAP devices have a very small screen; consequently, a WML "deck" is divided up into a collection of "cards" that can contain both the user interface and the content. So instead of presenting a large table listing all new mail on the server with all the details (sender's address, date, etc.), which would be good for HTML-capable Web browsers, it's better to split this information into several cards within one deck for WML.

The benefit of designing a card that lists only the mail's subjects, linked to the appropriate card holding the headers (sender, date, etc.) within the same deck, is a more comfortable user interface without any performance loss since all the headers are transferred within the same deck and therefore available locally without any server round-trips. By hiding detailed information on subsequent cards and presenting something akin to an index card on top, you can design a good WML deck.

On the other hand, putting too much detail in one deck exceeds the maximum (which is about 2 kilobytes per compiled deck sent from the WAP gateway). This is why I put just the header details in the deck, not the actual mail content, which could be quite a lot of text. After viewing the header details, a user can choose whether to fetch the content or continue browsing other e-mail.

On the subject of design considerations, mobile phones of course have no PC keyboard, although I sometimes wish they did - I hate typing in long text using the cumbersome keypad. Okay, this is a bad example, I thought, since e-mail often involves a lot of typing (especially when composing new mail) - but that's really up to the user: a mobile phone can certainly check new mail, and sometimes handle short text. But when using this example I strongly advise you not to ask for the mail account data with every login. Instead, provide your users with a database-based storage of their account data. As most of you (including me when I coded the example app) change the mail account settings during testing, asking the user to type in all settings at the start is okay. I also did this to keep things as simple as possible, and tried to focus on the WAP-related issues, not on storing login data into a database table (which is definitely not new to you).

Session Management on a Mobile Phone
Before going into the details of the code, I'd like to talk a bit about sessions. In general, ColdFusion provides the developer with a nice Web application framework including session management. If you haven't much experience in this area, session management is handled by the CF server via the use of cookies. Each user (browser) gets a session cookie set with a unique ID (CFID and CFTOKEN) that's sent back to the server with every request within the Web application. Alternatively, when cookies aren't supported on the client's browser, you can still keep the session management aware of its clients by passing the unique ID value of the client through every URL link your Web application has. This means you'll then have to append #SESSION.UrlToken# at every URL-like link, form target, or client-based JavaScript redirection. That way the CF server keeps informed about its clients even when no cookies are supported.

All this is true if you're dealing with the traditional Web and major browsers. But in terms of microbrowsers running on a mobile device that's not directly connected to your Web server (on mine it's connected through a WAP gateway server of the network supplier), things could be different. Fortunately, the WAP design group (www.wapforum.org), which consists of all major players and companies in the WAP world, has thought about this aspect too, and most WAP gateways keep track of cookies on behalf of the mobile devices and send them back to the server on each subsequent request (as normal browsers would). But to be on the safe side, I suggest you append the #SESSION.UrlToken# to each link in WML (you'll see this often throughout the listings).

Talking about links, WML is strictly XML; thus you'll have to watch out for all special characters, including the "&" sign we often use when passing parameters through a URL link. To put it simply, what would normally look like http://www. domain.com/page.cfm?param1=value1& param2=value2¶m3=value3 must be written in WML, that is, http://www.do main.com/page.cfm?param1=value1& amp;param2=value2&param3= value3. To make it easy to keep track of all XML-relevant special characters, you could also use the following line to output the link via the CF4.5 XmlFormat() function:

#XmlFormat("http://www.domain.com/
page.cfm?param1=value1¶m2=value2¶m3=value3")#
Getting Data Back from the WAP Device to the Application
Before I start describing the source code, there's one point left to discuss: how to pass input data back from the mobile device to the application. In traditional Web programming this is done through forms, with form fields passing values either as GET or POST requests to the action page (the latter is done more often, I suppose), as well as by using URL parameters appended to the action page's URL as the query string (the part after the "?") that emulates GET requests.

In WML you can submit the input values either as a POST request (using <postfield>s) or add them to a URL link (the equivalent of the GET method). As some gateways don't let <postfield>s pass values correctly (note that the simulators handle them correctly when in HTTP direct mode with no WAP gateway involved), I suggest you use the URL "get" variant, at least for now. A more detailed description of this can be found in Part 2 of Arehart's article, referenced earlier.

One nice feature of WML when dealing with form fields is that each value entered into a deck is directly available (in all cards within that deck) as a client-side WML variable.

<wml>
<card id="card1">
<do type="accept"><go href="#card2"/></do>
<p>
Password:
<input name="lastName" type="text"/>
</p>
</card>
<card id="card2">
<p>
You entered: $lastName
</p>
</card>
</wml>
In this snippet from a WML file the second card directly repeats what the user has entered on the first card's input field. So all input data is directly available in client-side WML variables for further use within the deck. We use these variables to attach the form field's input values as URL parameters to a link to the action pages.

Looking at the Code
Some of you may think this is too much information, coming as it does before the details of the source code. The advantage of this rather long introduction is that now you're aware of the more interesting aspects of WML development as you face it for the first time. Consequently, understanding the source code should be quite easy. So let's begin.

This application (see Figure 1 for the state diagram) consists of 11 listings that can be downloaded from www.sys-con.com/coldfusion/sourcec.cfm.

  1. application.cfm: Initializes session management
  2. index.cfm: Asks user for e-mail account settings
  3. initAccount.cfm: Stores account settings in user's session
  4. mainMenu.cfm: Wrapper including menu.cfm
  5. menu.cfm: Snippet that's included wherever menu should be presented
  6. checkMail.cfm: Checks user's mail server for e-mail and lists headers for overview
  7. openMail.cfm: Loads and opens full text of e-mail (eventually parceled out to multiple decks if too large)
  8. composeMail.cfm: Presents user interface for composing new e-mail or reply mail
  9. sendMail.cfm: Sends composed mail
  10. deleteMail.cfm: Deletes specified mail from user's mail server
  11. error.cfm: Invoked when error was caught with <CFTRY> and <CFCATCH>
Before describing each file in detail, I'd like to introduce the header that's necessary when using WML with CF tags:

<cfsetting showdebugoutput="No">
<cfcontent type="text/vnd.wap.wml"
reset="Yes"><?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="card1">
<p>Hello World</p>
</card>
</wml>
The <cfsetting> tag disables any debug output on the page to make sure your WML doesn't become invalid XML when debug output is sent to it at the end of the request. Next you'll see <cfcontent type="text/vnd. wap.wml" reset="Yes">, which is for setting the MIME type of the page to "WML", telling the client, "Yes, I'm really WML." The same is true with the XML and doctype declaration, which is a must for every WML page.

Now let's take a more detailed look at the source files:

application.cfm (Listing 1)
What we're doing here is enabling session management and checking for session timeouts and for a WAP/ WML or HTML client (see the first snippet above).

index.cfm (Listing 2)
This file (and all subsequent files) checks the REQUEST.isWap flag to determine what to send to the client, WML or HTML. As this file asks for a user's e-mail account settings, we have one card with many <input> fields for entering the POP3 and SMTP servers as well as the username and password for POP3 access. The more interesting part is where we set an action on one of the phone's buttons (here, the "accept" button, which is often directly beneath the display). You'll notice that I assigned a URL to that button, which is output from the CF variable #tmpTarget#. This variable is set up inside the <cfscript> block to become a URL string, sending every <input> field's value as a URL parameter by way of client-side WML variables. The content of #tmpTarget# looks like this (with the CFID and CFTOKEN replaced by the unique values of the current session):

"initAccount.cfm?CFID=1&CFT0KEN=95042334& initPop3=$initPop3&
initPop3Port=$initPop3Port&....."
Finally, after all "&"s have been escaped by XmlFormat(), the link is written into the <go> WML tag for assigning links to actions. That way the file initAccount.cfm gets all settings as URL parameters.

initAccount.cfm (Listing 3)
This file is passed in the account settings either as URL or FORM variables originating from either the WML or the HTML interface. After being captured by this template, they're stored in the session scope for further use. Finally, the menu.cfm file is included to show the menu.

mainMenu.cfm (Listing 4)
This file is nothing more than a wrapper including menu.cfm, which is convenient when a link should display only the menu content and nothing more. Then you simply set the link to mainMenu.cfm.

menu.cfm (Listing 5)
This file is the real menu, which is included wherever a menu is needed on a page. It contains links to checkMail.cfm, compose Mail.cfm, and index.cfm.

checkMail.cfm (Listing 6)
This file is more interesting. Here all headers are fetched from the user's mail server using <CFPOP> and stored in the ColdFusion query variable "qryMailHeaders". In WML a <select> list is populated with the e-mail subjects taken from the query. Each <option> tag jumps to a detail card containing all mail headers using the onpick="#cardName" attribute. Note that I escape all strings with Xml-Format() to avoid any conflicts when an e-mail contains special characters. After the card holding the <select> list has been written, a card displaying the mail's headers (such as sender, date, and subject) is generated for each mail. Each detail card also has links to open the e-mail, delete it from the server, or return to the main menu.

openMail.cfm (Listing 7)
As the name suggests, this file opens the mail, using <CFPOP> to fetch the entire e-mail, including the body. It won't fetch attachments since you can't use them on mobile phones - at least not yet. Next, the body of the e-mail is cropped after about a thousand characters and split over multiple decks, if necessary, to avoid a deck that exceeds the maximum size. Finally, the "back to inbox," reply, and delete links are written. While the delete link just calls deleteMail.cfm with the mail's message ID as a URL parameter, the reply link looks more interesting since it passes the sender and subject as escaped URL parameters to composeMail.cfm.

composeMail.cfm (Listing 8)
This file acts as the user interface for writing new mail or replies to mail. This double feature is possible through optional FORM/URL parameters holding the sender as well as the subject when acting as a reply mailer. The sender and the subject are populated into the corresponding <input> fields. The link to sendMail.cfm is written the same as it is in index.cfm (see Listing 2).

sendMail.cfm (Listing 9)
This file simply takes all param-eters necessary for sending e-mail (such as receiver, subject, etc.) either as FORM parameters when submitted from HTML or as URL parameters when originating from a WML deck. After the mail has been sent using <CFMAIL>, the main menu is shown.

deleteMail.cfm (Listing 10)
This file works much like openMail.cfm except that instead of loading the mail using <CFPOP>, it deletes it from the server using <CFPOP action="DELETE" ...>.

error.cfm (Listing 11)
This file is invoked within a <CFCATCH> block used in critical sections where the mail server is involved. Whenever an error occurs with the mail server (most often a typo in the account settings dialog at the mail server's address), this template is loaded, trying to present the error message. The file could be extended to serve as a general error-handling template for the <CFERROR> tag with minimal effort, resulting in application-wide error handling.

Summary
This article is intended to be an introduction to WAP/WML development with ColdFusion based on the example of an e-mail service application. My goal was to remove all the obstacles and present you with a nice but simple example app. Advanced WML aspects - for example, the WMLScript client-side scripting language (like JavaScript for the traditional Web) - is out of this article's scope. To explore these advanced techniques (after having mastered the basics), I recommend you take a look at some of the books available on WAP/WML development.

About 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.

CFDJ LATEST STORIES . . .
Adobe and ARM are gonna put Flash Player 10 and AIR, the stuff of web video and rich Internet apps, on ARM widgets by the second half of next year. They mean phones, set-tops, MIDs, TVs, car mojo and personal media devices, which have so far only had access to Flash Lite, not the best ...
Of all domestic air carriers, I like Continental the most. They showed Mamma Mia and the food was bearable. Last month, I was in the air for 14 hours flying to Japan, and now the trip across the USA is a piece of cake. I have only carry luggage with me. This small bag has all the cloth...
I’ll just give you one example. Last week my colleague and I were running a private Flex workshop for software architects of a large corporation who are about to start development with Flex. Needless to say that they are smart and experienced software professionals. Some of them alre...
A round-up of the many themes and topics of interest to infrastructure architects, developers and IT managers featuring at SYS-CON's Cloud Computing Expo being held November 19-21, 2008 at The Fairmont Hotel in San Jose, California. The conference is expecting a record turnout of senio...
AIR adds to Flex has a pretty straightforward API for working with local files and directories. There is a simple mechanism of installing and upgrading AIR applications. If you want, you can digitally sign them too. AIR 1.5 introduces local encryption, which means that you can encrypt...
Reading conference speaker's agreements may reveal some interesting gems. Since I don't have a PR agent, I have to make the following public statement by myself: "I'm not going to damage anyone's reputation (including developers of PureMVC framework) for abuse of design patterns. I'm r...
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS
SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021


SYS-CON FEATURED WHITEPAPERS

MOST READ THIS WEEK
ADS BY GOOGLE