Wt: C++ Web Toolkit Library Lets You Write Scripting-Independent Web Apps

Wt (pronounced 'witty') is a C++ library and application server for developing and deploying web applications. Although Wt supplies a GUI, it is not your typical "framework", which locks you into someone's preconceived idea of how applications should be structured. Rather, Wt is widget-centric, and although inspired by existing C++ GUIs, it offers complete abstraction of any web-specific implementation details, all the way down to event handling and graphics support. It's probably not a coincidence that Wt is named similarly to the ever-popular Qt application development system!

In fact, none of today's so-called "page-based frameworks" (built on PHP or JSP/JSF derivatives) for developing web applications make abstraction of the peculiarities of the underlying implementation technologies. As a consequence, a developer must gain familiarity with a panoply of ever-changing technologies, including HTML/XHTML, JavaScript, CSS, AJAX, CGI, DHTML, SVG/VML/Canvas—just to name a few. Moreover, as soon as you drive a stick into the ground and choose a technology such as AJAX or JavaScript, you must take responsibility for graceful degradation when these pieces are missing in action due to or disabled for local security reasons. Little has changed in the structure of applications that follow the primarily page-centric paradigm of 1990s HTML. This means that you will need to design and maintain manually your client-server communication when using advanced AJAX techniques.

Generating HTML code or filling HTML templates is prone to security problems such as Cross-Site-Scripting (XSS), by unwillingly allowing JavaScript to be inserted in the page. Ironically, template frameworks cannot avoid this because as a developer you need to be able to insert self-written JavaScript to improve your web application.

In contrast, a web application developed with Wt is written in only one compiled language (C++), from which the library generates the necessary HTML/XHTML, JavaScript, CGI, or AJAX code. The responsibility of writing secure and browser-portable web applications is handled by Wt. For example, if available, Wt will maximally use JavaScript and AJAX, but applications developed using Wt will also function correctly when AJAX is not available, or when JavaScript is disabled, reverting to a plain HTML/CGI mechanism for communication between browser and server.

Typical use scenarios:

  • Web-based GUIs for embedded systems
  • Web-based GUIs that require integration with (existing) C++ libraries
  • Creating a port of existing C++ desktop applications to the web

Some benefits of using Wt:

  • Develop web applications like you develop C++ desktop applications.
  • Provides plain widgets, which work regardless of JavaScript availability.
  • Enables more polished or advanced functionality when JavaScript is available (without re-coding)
  • Built-in HTTPD and FastCGI for easy development and deployment.
  • A single specification for both client- and server-side validation and event handling (when using stateless slot implementations).
  • Generates standards compliant HTML or XHTML code.
  • Portable, anti-aliased graphics with VML, SVG, or HTML 5.
  • No exposure of business logic, which stays at the server.
  • Page load time is limited only by screen complexity, not application size.

Installation

Installing Wt for Windows is a bit harder than implementing it on a Linux host, primarily because there isn't anything as simple as Linux package management on Windows. So, it becomes a bit of a scavenger hunt, although there is a nice how-to document. Basically, you are responsible for locating the suggested versions of BoostPro Boost library (currently, 1.34.1). BoostPro requires asio, the asynchronous I/O model for C++. This is theoretically included in BoostPro 1.35 although I didn't test it out. These components in turn require cmake, a freeware "make" type utility.

Hello Wt!

You'll start off with a "hello world" type app that provides a simple CGI type form and see how this design can be realized by a C++ app. Unlike most apps that I write about, you can actually run it for yourself right now on the web! What you'll see first is a classic web form presentation shown in Figure 1. After you enter your name and click the Submit button ("Greet me."), it rewrites the page and more-or-less you are back to the initial state, as shown in Figue 2.

Figure 1: Hello world forms (entering text)

[Wt2.jpg

Figure 2: Hello world forms (after clicking Submit)

So, take a walkthrough of this program and see how it was done. First, keep in mind that most GUI "hello world" apps often run 50 to 100 lines of code.

 1 #include <WApplication>
 2 #include <WBreak>
 3 #include <WContainerWidget>
 4 #include <WLineEdit>
 5 #include <WPushButton>
 6 #include <WText>
 7
 8 using namespace Wt;
 9
10 class HelloApp : public WApplication
11 {
12 public:
13    HelloApp(const WEnvironment& env);
14
15 private:
16    WLineEdit *nameEdit_;
17    WText *greeting_;
18
19    void greet();
20 };

Wt: C++ Web Toolkit Library Lets You Write Scripting-Independent Web Apps

You start off deriving your application from WApplication and you must implement a constructor, called in your case HelloApp(), which will be called with information about the new session and the initial request.

21
22 HelloApp::HelloApp(const WEnvironment& env)
23    : WApplication(env)
24 {
25   setTitle("Hello world");               // application title
26
27    root()->addWidget(new WText("Your name, please ? "));
      // show some text
28    nameEdit_ = new WLineEdit(root());    // allow text input
29    nameEdit_->setFocus();                // give focus
30
31    WPushButton *b = new WPushButton("Greet me.", root());
      // create a button
32    b->setMargin(5, WWidget::Left);       // add 5 pixels margin
33
34    root()->addWidget(new WBreak());      // insert a line break
35
36    greeting_ = new WText(root());        // empty text
37
38    // Connect signals with slots
39
40    b->clicked.connect(SLOT(this, HelloApp::greet));
41    nameEdit_->enterPressed.connect(SLOT(this, HelloApp::greet));
42 }
43

The HelloApp::HelloApp() constructor initializes the web page and sets up event handlers. In Lines #25-36, you are simply adding all the elements to your form dynamically. The WText widget supplies static text, the WLineEdit widget turns into an INPUT tag, and WPushButton will handle the Submit action later. In Lines #40-41, you link in the event handlers for your app that will do the real work. Specifically, you want to run the greet() method when either the button is clicked OR someone is in the INPUT area and hits the "Enter" key.

44 void HelloApp::greet()
45 {
46    // Update the text, using text input into the nameEdit_ field.
47    greeting_->setText("Hello there, " + nameEdit_->text());
48 }

So now, the greet() method is what happens when you want some action to occur after the button is clicked or the equivalent action of pressing Enter inside the INPUT area. If you recall, back on Line #36, you created the greeting object as a new static text (WText) widget but left it empty. Because the HTML on the page is essentially rendered in the order that objects are created, the greeting is the last thing on your page. Intially, it is invisible because it has no value and then after the button is clicked, you're copying the data from the WLineInput widget and calling WText.setText() and so it displays "Hello there so-and-so" on the page.

49
50 WApplication *createApplication(const WEnvironment& env)
51 {
52    // You could read information from the environment to decide
53    // whether the user has permission to start a new application
54    return new HelloApp(env);
55 }
56
57 int main(int argc, char **argv)
58 {
59    return WRun(argc, argv, &createApplication);
60 }

The remaining code in Lines #50-60 constitutes more of the frame initialization and application creation, which is bookkeeping stuff as far as you are concerned in this article.

Wt: C++ Web Toolkit Library Lets You Write Scripting-Independent Web Apps

Code Generation

So, how is this different than just coding up a bunch of stuff in an HTML FORM tag area? Plenty! In the HEAD area of the document, there are 800+ lines of JavaScript code planted to handle the responses to various events as they happen. A good bit of this, perhaps 20%, is related to handling drag-and-drop events in JavaScript. If you want to see the nitty gritty, go run the app and then right-click on a blank area in the page and choose "View Source."

Eventually, you get to the BODY that was generated. You can see that it is setting up several global event handlers for the entire page in the BODY tag. Then, you get a spanned area with the "Your name, please?" text, followed by the INPUT area, and the BUTTON. Both the INPUT and BUTTON are loaded with JavaScript event handlers. Last, but not least, there is a load of Inline Frames (IFRAME) with data pertaining to your Widgets.

<body onload="setTimeout(Wt.private.load,0);"
      onmousemove="return Wt.private.dragDrag(event);"
      onmouseup="return Wt.private.dragEnd(event);"
      ondragstart="return false;">
<div id="o3e03"><div id="o3e04"></div>
<div id="o3e05"><span id="o3e10">Your name, please? </span>
<input id="o3e11"
       name="o3e11"
       size="10"
       type="text"
       onkeydown="var s='';if((event.keyCode &&
          event.keyCode == 13)){s='sa28';}if(s.length!=0)
          {Wt.private.update(this, s, event, true);}" value="">
</input>

<button id="o3e12"
        type="button"
        onclick="Wt.private.update(this, 'sa27', event, true);"
        style="margin-top:0.0px;margin-right:0.0px;
               margin-bottom:0.0px;margin-left:5.0px;">Greet me.
</button>

<br id="o3e13" /><span id="o3e14"></span></div>
<iframe id="o3e06"
        class="Wt-resource" name="o3e06"
        src="?wtd=pm5i5XOtcGx7paaYMTZgbRd7Pae3xORU&
           amp;resource=o3e06&rand=627318544">
</iframe>
<iframe id="o3e07"
          class="Wt-resource" name="o3e07"
          src="?wtd=pm5i5XOtcGx7paaYMTZgbRd7Pae3xORU&
               resource=o3e06&rand=627318544">
</iframe>
<iframe id="o3e08"
        class="Wt-resource" name="o3e08"
        src="?wtd=pm5i5XOtcGx7paaYMTZgbRd7Pae3xORU&
             resource=o3e06&rand=627318544">
</iframe>
<iframe id="o3e09"
        class="Wt-resource" name="o3e09"
        src="?wtd=pm5i5XOtcGx7paaYMTZgbRd7Pae3xORU&
             resource=o3e06&rand=627318544">
</iframe>
<iframe id="o3e0a"
        class="Wt-resource"
        name="o3e0a"
        src="?wtd=pm5i5XOtcGx7paaYMTZgbRd7Pae3xORU&
             resource=o3e06&rand=627318544">
</iframe>
<iframe id="o3e0b"
        class="Wt-resource"
        name="o3e0b"
        src="?wtd=pm5i5XOtcGx7paaYMTZgbRd7Pae3xORU&
             resource=o3e06&rand=627318544">
</iframe>
<iframe id="o3e0c"
        class="Wt-resource"
        name="o3e0c"
        src="?wtd=pm5i5XOtcGx7paaYMTZgbRd7Pae3xORU&
             resource=o3e06&rand=627318544">
</iframe>
<iframe id="o3e0d"
        class="Wt-resource"
        name="o3e0d"
        src="?wtd=pm5i5XOtcGx7paaYMTZgbRd7Pae3xORU&
             resource=o3e06&rand=627318544">
</iframe>
<iframe id="o3e0e"
        class="Wt-resource"
        name="o3e0e"
        src="?wtd=pm5i5XOtcGx7paaYMTZgbRd7Pae3xORU&
             resource=o3e06&rand=627318544">
</iframe>
<iframe id="o3e0f"
        class="Wt-resource"
        name="o3e0f"
        src="?wtd=pm5i5XOtcGx7paaYMTZgbRd7Pae3xORU&
             resource=o3e06&amp;rand=627318544">
</iframe>
</div>

<script type="text/javascript">
   /*<![CDATA[*/

   /* ]]> */
</script>

Conclusion

Well, you could say that you haven't really pushed the envelope with your Hello World app, but I thought it would be more useful to take a really close look at a simple app rather than just seeing a small bit of a sophisticated app. In reality, there's lots of Wt example programs to look at which show off things like drag-and-drop, chat, calendar, file tree explorer, email composer, and bar graphs. There is some fascinating stuff such as the Composer widget that encapsulates the whole set of Gmail type message composing, including managing uploaded attachments and letting them transfer asynchronously. Any one of these would probably need as thorough a treatment as you had here to explain them, but again the point is that you can simply instantiate them, connect signals to slots, and begin coding immediately.

Also, and it should be apparent, I hope that your C++ app on the back end of this web-fronted GUI has all the capabilities it would normally have with respect to connecting with databases, reading and writing files, and all the real work that apps have to do to fulfill their business logic. Wt has been a bit of a latecomer to all the web application frameworks, but it comes at a time when the freight of many of these is simply overwhelming and being able to work in a familiar C++ framework is perhaps just what the doctor ordered.

About the Author

Victor Volkman has been writing for C/C++ Users Journal and other programming journals since the late 1980s. He is a graduate of Michigan Tech and a faculty advisor board member for the Washtenaw Community College CIS department. Volkman is the editor of numerous books including, C/C++ Treasure Chest and is the owner of Loving Healing Press. He can help you in your quest for open source tools and libraries; just drop send an email to sysop@HAL9K.com



About the Author

Victor Volkman

Victor Volkman has been writing for C/C++ Users Journal and other programming journals since the late 1980s. He is a graduate of Michigan Tech and a faculty advisor board member for Washtenaw Community College CIS department. Volkman is the editor of numerous books, including C/C++ Treasure Chest and is the owner of Loving Healing Press. He can help you in your quest for open source tools and libraries, just drop an e-mail to sysop@HAL9K.com.

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The operational costs of managing an x86 base are taxing IT budgets, making it difficult to fund and staff new initiatives. Today's IT organization must seek efficiencies in its operations and shift to a more agile infrastructure that's flexible enough to adapt to future changes in the business. Read this Q & A session with Jed Scaramella, research manager for IDC's Enterprise Platforms and Data Center Trends, to learn how the integrated nature of the blade platform delivers critically needed efficiencies …

  • The impact of a data loss event can be significant. Real-time data is essential to remaining competitive. Many companies can no longer afford to rely on a truck arriving each day to take backup tapes offsite. For most companies, a cloud backup and recovery solution will eliminate, or significantly reduce, IT resources related to the mundane task of backup and allow your resources to be redeployed to more strategic projects. The cloud - can now be comfortable for you – with 100% recovery from anywhere all …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds