# Web Application Extension Service

This chapter covers the fundamental objects of the web application extension (wax) service. This service provides the support for low level HTTP transaction as well as high level XHTML page generation and CGI scripts execution.

All web application extension objects are located in the `afnix-wax` service module. This module must be loaded prior any operation. Multiple calls to the module initialization routine are harmless. The interpreter method `library` loads a specific service module by name. When the module has been loaded, the objects are available in the `afnix:wax` nameset. Unlike a module, a service module might refer to objects associated with other module. Although the objects are visible internally to the engine, their symbols are not exported until a call with the `library` method has been made.

interp:library "afnix-wax"

## Page service objects

The `XhtmlRoot` class is the primary interface to generate xhtml page. The class is derived from the `XmlRoot` class and the `Mime`object. for this reason, creating a xhtml page is equivalent to add xml nodes to the page. The xhtml version is assumed to be 1.1.

### Page creation

The `XhtmlRoot` constructor takes a string argument which is the title page. When the root page is created, a head and body nodes are automatically created. Once created, it is possible to retrieve the head and body nodes from the root node. The head and body nodes are part of the html node which is automatically instantiated as a `XhtmlHtml` object. The html node can always be retrieved from the root node with the `get-child` xml method.

# create a new xhtml page const page (afnix:wax:XhtmlRoot "AFNIX wax service") # get the head node const head (page:get-head) # get the body node const body (page:get-body)

The head and body nodes are part of the html node which is automatically instantiated as a `XhtmlHtml` object. The html node can always be retrieved from the root node with the `get-child` xml method. The root methods `get-head` and `get-body` are convenient methods that ease the page design by eliminating the references to the html node.

# create a new xhtml page const page (afnix:wax:XhtmlRoot "AFNIX wax service") # get the html node const html (page:get-child "html") # get the head node const head (html:get-head) # get the body node const body (html:get-body)

### Page header

The `XhtmlHead` class is the xml node that handles the xhtml head. The object is automatically created when calling the `XhtmlRoot` constructor. During the construction process, the head is automatically set with a title. Once created, the head can be filled with meta information and styles. The `add-meta` method is designed to add meta information, while the `add-style` add a link node with a style reference to the head.

# add a meta tag head:add-meta "copyright" "© 2000" # add a style path head:add-style "/style.css"

The `add-meta` method adds a `XhtmlMeta` object which is a xml tag node. The first argument is the meta descriptor while the second argument is the meta content. Note that the `add-meta` method can be simulated by calling the `XhtmlMeta` constructor and then adding the node to the head node.

# create a meta node const node (afnix:wax:XhtmlMeta "copyright" "© 2000") # add the node to the head head:add node

The `add-style` method adds a `XhtmlStyle` object which is a xml tag node. The string argument is the url style sheet path which gets automatically transformed to the form @import(url). Note that the `add-style` method can be simulated by calling the `XhtmlStyle` constructor and then adding the node to the head node.

# create a style node const node (afnix:wax:XhtmlStyle "/style.css") # add the node to the head head:add node

### Page body

The `XhtmlBody` class is the xml node that handles the xhtml body. The object is automatically created when calling the `XhtmlRoot` constructor. Once created, the body node can be filled with any valid xhtml node. Since the node are initially xml tag node, it is always possible to create a tag by name and set the attributes and child nodes manually.

# create a new xhtml page const page (afnix:wax:XhtmlRoot "AFNIX wax service") # get the body node const body (page:get-body) # add a node body:add-child node

### Page emission

Since the `XhtmlRoot` object is a xml root node, the node can be used to write the complete hierarchy. The xml node node provides the `write` method that write a xml tree into a buffer of an output stream.

# create a new xhtml page const page (afnix:wax:XhtmlRoot "AFNIX wax service") # write to the output stream page:write

Another mechanism for writing the page is to use the fact that the `XhtmlRoot` class implements also the `Mime` interface. With this in mind, the `XhtmlRoot` can be used within the `HttpReply`. This method is particularly useful when writing automated page generation, such like CGI scripts.

# create a new xhtml page const page (afnix:wax:XhtmlRoot "AFNIX wax service") # create an http reply object const reply (afnix:wax:HttpReply) # write the page as a mime object reply:add-buffer page # write the result to the output reply:write

## Page design objects

The wax service module is designed to provide several object that ease the task of creating a xhtml page. Such objects range from comment to table. Most of the time, the construction is simple the resulting node only need to be added to the page tree. When it comes to add text, the problem is becoming more subtle and is discussed later in this section.

### Comment node

Adding a comment is done with the `XmlComment` class which take the comment string in the constructor. Once created, the comment node can be added to the tree.

# add a comment to the body node body:add-child (afnix:xml:XmlComment "this is a comment")

### Node style class

When the xhtml page is combined with the cascaded style sheet (CSS), the xhtml node tag often uses a class name to refer to a particular style. The class style is just a node attribute which can be set with the `add-attribute` method. However, most of the time, the library provides object which have the style as the first argument in the constructor. For example, the `XhtmlDiv` constructor take 0 or one argument. With one argument, the string argument is used as the style attribute.

# create a xhtml div with a class attribute const div (afnix:wax:XhtmlDiv "nice") # create a xhtml div and set the class manually const div (afnix:wax:XhtmlDiv) div:set-attribute "class" "nice"

### Adding text paragraph

Adding text to a page is not a trivial task when it comes to deal with text style. By default, a piece of text is stored in the `XmlText` node. Using this node is easy. However, in a programming context, its use can become heavy. For this reason, all xml nodes provide the `parse` method which can be used to add a xml tree to the calling node. When it comes to add text that includes rendering tag, this method is quite handy.

# add a text with some piece in italic node:parse "this is a <i>simple</i> method"

The `XhtmlPara` node is the preferred node for adding text to a xhtml page. The node takes optionally the style name in the constructor. A boolean flag can also be used to create an empty paragraph node.

# create a paragraph node with a style const p (afnix:wax:XhtmlPara "title") # add some text p:parse "the paragraph text"

### Adding reference

Adding reference or hyperlink to a page is achieved with the `XhtmlRef` class. Most of the time, the object is built with a uri and a text. when the node has been created, the node can be added to the page tree.

# create a hyperlink const node (afnix:wax:XhtmlRef "http://www.afnix.org" "afnix") # add the node in a paragraph p:add-child node

### Formatting elements

The `XhtmlDiv` and `XhtmlHr` classes are the basic formatting xhtml elements. The `XhtmlDiv` is a grouping element and the `XhtmlHr` is a simple horizontal ruler element. Both classes take 0 or one argument which is the style name.

# create a div element const div (afnix:wax:XhtmlDiv "menu") # create a ruler element const hr (afnix:wax:XhtmlHr)

## Managing table

The wax service module provides an extensive support of he xhtml table element. There are basically two strategies for creating a table. One is to use the html elements or the other is to use a print table object and automatically feed the xhtml table. The first method provides a better control while the second one is easier to use.

### The table element

The `XhtmlTable` class is the class that manages xhtml table. As usual, a default style name can be specified in the constructor. Eventually, a default table row and table data default style can also be specified. Such default value are used when creating a new row with the `new-row` method.

# create a table element with a default tr and th/td style const tbl (afnix:wax:XhtmlTable "text" "text" "text") # get a new row with a default style const tr (tbl:new-row)

In the previous example, a table is created with a default style for the table row. When a new row is created, the default style is used for that row. If there is no default style, the row is created without a style. Note that the `new-row` method takes also a style argument that overwrites the default one.

### Building the table

A table is built by adding row and data element into the rows. A row is created with the `new-row` method or the object can be constructed directly and added to the node with the `add-child` method. The `XhtmlTr` class is the table row class.

# get a new row with a default style trans tr (tbl:new-row) # create a row directly trans tr (afnix:wax:XhtmlTr "text")

When a row has been created, the data can be added to the row. Normally, the `new-data` method is used to create a new table data element. If a default style is defined in the table row, the table data element is built with that style. The `new-head` method can also be used to create table header element. Again, if a default table header style exists in the table row, the element is built with that style. The `XhtmlTd` class is the table data class and the `XhtmlTh` class is the table header class.

# get a new data element trans td (tr:new-data) # create new head element trans th (tr:new-head)

When the table data node has been created, the `parse` method or the `add-child` method can be called to add other nodes. another method for building the table is to use the `add-table` method which uses a print table object. In such case, the table rows and data elements are automatically added in the table.

### The table structure

The table can be designed directly with table rows with table headers and table data elements. Another method, which is more structured is to use the table head, table body and table footer elements. The `XhtmlThead` class is the table head element class. The `XhtmlTbody` class is the table body element class. The `XhtmlTfoot` class is the table footer element class. These classes behaves exactly like the `XhtmlTable` and are in fact all derived from the `XhtmlTelem` class.

# create a xhtml table const table (afnix:wax:XhtmlTable "text") # create a table body const tbody (afnix:wax:XhtmlTable "text" "text" "text") # add a print tbl in the body tbody:add-table ptbl # add the body to the table table:ad-child tbody

A table caption node can also be set with the `set-caption` method. The method simply creates a `XhtmlCaption` node and adds it to the table. The caption text is part of the method call which is used by the caption node constructor. It is also possible to create the caption node by calling the `XhtmlCaption` constructor and adding it to the table with he `add-child` method.

# create a xhtml table const table (afnix:wax:XhtmlTable "text") # set a table caption table:set-caption "the afnix table system"

The table structure can also be defined with the `XhtmlCgr` class which corresponds to the xhtml column group element. The column group element is designed to support the col element that formats the table column.

# create a table const table (afnix:wax:XhtmlTable "text") # set the table with to 100% table:add-attribute "width" "100%" # create a column group table:add-child (const cgr (afnix:wax:XhtmlCgr)) # add a column with 30% width cgr:add-child (afnix:wax:XhtmlCol "30%") # add a column with 70% width cgr:add-child (afnix:wax:XhtmlCol "70%")