## Creating a Web Application

### Introduction

This section will guide you through all the code you have to write to create an interactive web application using libzeep. The way this works in libzeep looks a lot like popular frameworks found for Java. If you're familiar with JSP and e.g. Struts, you'll notice the similarities.

### The building blocks

It is very inconvenient to write HTML code in C++ directly using string concatenations and streams. Therefore, a separation has been made. All HTML is put into XHTML template files. These template files can use special tags to generate HTML tags based on data provided by the server application. A script language that looks a lot like JSP 'Expression Language' (or `el` in short) is used to program conditional constructs. Communication between this `el` script and the server application is done via `el::object` data objects.

### Hello world!

Let's start with a simple hello world example. We first create a template file, save this file as `hello.xhtml`.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xhtml PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/1999/xhtml">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
      <title>Hello</title>
    </head>
    <body>
      <p>Hello, world!</p>
    </body>
    </html>

This is a very simple, strict XHTML 1.1 file. We will serve it with our server:

    #include <zeep/http/webapp.hpp>
    #include <boost/bind.hpp>

    using namespace std;

    class MyWebApp : public zeep::http::webapp
    {
      public:
        MyWebApp();

        void handle_welcome(const zeep::http::request& request,
               const zeep::http::el::scope& scope, zeep::http::reply& reply);
    };

    MyWebApp::MyWebApp()
    {
      mount("",      boost::bind(&MyWebApp::handle_welcome, this, _1, _2, _3));
    }

    void MyWebApp::handle_welcome(const zeep::http::request& request,
               const zeep::http::el::scope& scope, zeep::http::reply& reply)
    {
      create_reply_from_template("hello.xhtml", scope, reply);
    }

    int main()
    {
      MyWebApp server;
      server.bind("0.0.0.0", 80);
      server.run(1);
    }

By calling `mount` with the empty string, we tell libzeep to redirect all access to the base URL to handle_welcome. This means that visiting the URL http://localhost/ should now return a page containing the string 'Hello, world!'.

### Using forms

Now lets create a form to pass some data from the browser to the server and back. Save the following file as `form.xhtml`.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xhtml PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/1999/xhtml">
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:zeep="http://www.cmbi.ru.nl/libzeep/ml">
    <head>
      <title>Form example</title>
    </head>
    <body>
      <zeep:if test="${name}">
        <p>Hello ${name}!</p>
      </zeep:if>
      <p>Please enter your name and press the Submit button</p>
      <form id="myForm" action="salute" method="get">
        <label>Name: <input id="name" type="text" name="name" value="${name}"/></label>
        <input type="submit" value="Submit" />
      </form>
    </body>
    </html>

We add the zeep prefix to our html tag, it has the value `"http://www.cmbi.ru.nl/libzeep/ml"` which is the same as the default value for the `ns` parameter in the `zeep::http::webapp` constructor. Note that the input tag has an attribute with value '${data}'. This is a piece of expression language script. This will be explained below:

    #include <zeep/http/webapp.hpp>
    #include <zeep/http/webapp/el.hpp>
    #include <boost/bind.hpp>

    using namespace std;

    class MyWebApp : public zeep::http::webapp
    {
      public:
        MyWebApp();

        void handle_welcome(const zeep::http::request& request,
               const zeep::http::el::scope& scope, zeep::http::reply& reply);
        void handle_salute(const zeep::http::request& request,
               const zeep::http::el::scope& scope, zeep::http::reply& reply);
    };

    MyWebApp::MyWebApp()
    {
      mount("",       boost::bind(&MyWebApp::handle_welcome, this, _1, _2, _3));
      mount("salute", boost::bind(&MyWebApp::handle_salute, this, _1, _2, _3));
    }

    void MyWebApp::handle_welcome(const zeep::http::request& request,
               const zeep::http::el::scope& scope, zeep::http::reply& reply)
    {
      create_reply_from_template("form.xhtml", scope, reply);
    }

    void MyWebApp::handle_salute(const zeep::http::request& request,
               const zeep::http::el::scope& scope, zeep::http::reply& reply)
    {
      zeep::http::parameter_map params;
      get_parameters(scope, params);

      string name = params.get("name", "").as<string>();

      zeep::http::el::scope sub(scope);
      sub.put("name", name);

      create_reply_from_template("form.xhtml", sub, reply);
    }

    int main()
    {
      MyWebApp server;
      server.bind("0.0.0.0", 80);
      server.run(1);
    }

This time, we add a new handler for the 'salute' page. The form has an action that points to this salute page. As can be seen in the `handle_salute` method, we first collect the parameters passed in. Parameters are accessed by name. We then create a sub scope of the scope passed in. In this sub scope we put the value of the parameter so that the XHTML processor can access it. And then we return a reply based on the contents of the `form.xhtml` template and the contents of the sub scope we created.

### Using `el` script

`el` means Expression Language. It is a script language that tries to be like http://en.wikipedia.org/wiki/Unified_Expression_Language. The objects can be created in the C++ server code using the `zeep::http::el::object` class. Object created this way are then stored in an `zeep::http::el::scope` object and passed along to the XHTML processing code.

`zeep::http::el::object` objects can contain simple data and arrays. E.g., to create an array you could write:

    using namespace zeep::http;

    vector<el::object> ints;
    for (int i = 0; i < 10; ++i)
    {
    	el::object int_object;
    	int_object["value"] = i;
    	ints.push_back(int_object);
    }

    scope.put("ints", el::object(ints));

And then you can access this in the XHTML:

    1: ${ints[1].value}, 2: ${ints[2].value}

Which should output "1: 1, 2: 2"

### Processing Tags

The method `create_reply_from_template` takes the name of a template file and a scope to generate the output XHTML. We've already seen that `el` scripts are processed by this method. But there is more, several special tags in the template are processed in a special way. These tags are in a separate XML namespace. You can change this name space using the `ns` parameter in the `zeep::http::webapp` constructor, the default is `http://www.cmbi.ru.nl/libzeep/ml`.

In the template for the form example above you might have noticed the `<zeep:if>` tag. This tag takes one attribute called `test` and the value of this tag is interpreted as a `el` script. If the script evaluates to something other than empty, zero or false, the content of the `<zeep:if>` tag is included, otherwise it is discarded in the output.

There are several predefined processing tags which are summarized below. You can also add your own processing tags using the `zeep::http::webapp::add_processor` method. This method takes a `std::string` parameter for the name of the tag and a `processor_type` parameter which is a call back function.

Table 1. List of predefined processing tags

tag name (without prefix) | Description | Example
--- | --- | ---
include | Takes one parameter named `file` and replaces the tag with the processed content of this file | `<zeep:include file="menu.xhtml"/>`

if

Takes one parameter named `test` containing an `el` script. This script is evaluated and if the result is not empty, zero or false, the content of the `if` tags is inserted in the output. Otherwise, the content is discarded.

    <zeep:if test="${not empty name}">
      Hello ${name}
    </zeep:if>

iterate

Takes two parameters, `collection` which contains an `el` script that evaluates to an array `el::object` and a name in `var`. The content of the `iterate` tag is included for each value of `collection` and `var` will contain the current value.

    <ul><zeep:iterate collection="${names}" var="name">
      <li>${name}</li>
    </zeep:iterate></ul>

for

Takes three parameters. The parameters `begin` and `end` should evaluate to a number. The parameter `var` contains a name that will be used to hold the current value when inserting the content of the `for` tag in each iteration of the for loop between `begin` and `end`.

    <zeep:for begin="1" end="3" var="i">
      ${i},
    </zeep:for>

number

Format the number in the `n` parameter using the `f` format. This is limited to the formats `'#.##0'` and `'#.##0B'` for now. The first formats an integer value using thousand separators, the second tries to format the integer value in a power of two multiplier (kibi, mebi, etc.) with a suffix of `B`, `M`, `G`, etc.

    <zeep:number n="1024" f="0.00#B"/>
    Will output 1K

options

This tag will insert multiple `<option>` tags for each element in the `collection` parameter. This `collection` paramter can contain an array of strings or it can contain an array of `el::object`. In the latter case, you can specify a `value` and `label` parameter to name the value and label fields of these objects. A `selected` parameter can be used to select the current value of the options.

    <zeep:options collection="${names}"
      value="id" label="fullName" selected="1" />

option

Generate a single `<option>` tag with a value as specified in the `value` parameter. If `selected` evaluates to the same value as `value`, the option is selected. The content of the `<option>` tag is inserted in the final tag.

    <zeep:option value="1" selected="${user}">
      John Doe
    </zeep:option>

checkbox

Create an `<input>` tag with type `checkbox`. The parameter `name` is used as name attribute and the parameter `checked` is evaluated to see if the checkbox should be in checked mode.

    <zeep:checkbox name='cb1' checked='${true}'>
      Check me
    </zeep:checkbox>

url

The url processing tag creates a new variable in the current scope with the name as specified in the `var` parameter. It then creates a list of all original HTTP parameters for the current page. You can override these parameter, and add new ones, by adding `<param>` tags in the `<url>` tag.

    <zeep:url var="next">
      <zeep:param name='page' value='${page + 1}'/>
    <zeep:url>
    <a href="${next}">Next page</a>

param | see `url` above. |

embed

This tag takes the content of the `var` parameter which should contain valid XML and puts the processed value in the document.

    <zeep:embed var="&lt;em&gt;hello, world!&lt;/em&gt;"/>