Developing a Whitebeam Application

Site Map
 
Home
 
Application Guide
  Quick Start
  PHP and ASP
  Writing Apps
  Applications
  Tutorials
  Samples
Reference
Community
Contact Whitebeam
To-Do
Download
Credits
Licence
Whitebeam Users
 
 
 

Developing a Whitebeam Application

Introduction

Whitebeam provide a 'complete solution' for designing, implementing, testing and hosting web based applications. The solution has been designed from the ground up with reliability, maintainability and rapid development in mind. Developing highly functional web sites using the Whitebeam System is very simple once a few key concepts have been mastered.

This quick start guide explains the basic concepts surrounding Whitebeam server-side environment, the JavaScript language and the techniques for debugging your Web application. This overview summarise the main elements of the system and where necessary points the reader at more detailed descriptions.

Other key resources for the developer are:

This quick start guide assumes that the reader is already familiar with JavaScript, HTML and XML technologies and has also read the Whitebeam White Paper "How a Whitebeam Application Works".

SectionSummary
IntroductionThis section
The ApplicationThe elements of a Whitebeam application.
AdministrationMaking your site live.
SourceThe application source files.
StructureThe elements of a site.
Form DataData from browsers.
SessionsHow to tracking user sessions.
Access ControlProtecting access to parts of your site.
TemplatesAdding functionality to your site.
FilesHow to read files from a client.
Debug and TestTesting your site.
Virtual Server FilesFile layouts in your site.
Hints and TipsTo help your development.

What is a Whitebeam Application

A 'basic' web site comprises a number of 'static' resources, or files that are placed on a web server. The role of the web server is to locate a specific file when requested, and to return that to the client browser. The site is described as 'static' because the entire content of the site is determined when the web author designed the pages. Nothing changes! In this model, the web server is relegated to the role of a file server - using the HTTP protocol to distribute the files.

The Whitebeam environment allows the content of the site to be 'dynamically' generated - that is the content of a page is determined programmatically when a client accesses a site. To do this the web author creates a 'distributed' application. The images and static content of the application remain the same. But 'dynamic' behaviour is added in the form of Pattern Pages.

The application now comprises the following 'intelligent' entities, that have responsibility for different areas of the application:

EntityResponsibilities
Web BrowserResponsible for the graphical user interface presented to the user. This consists of traditional HTML and active 'JavaScript'. The browser and the clients access device (e.g. a PC) executes all the code to form the applications user interface.
Whitebeam Presentation EngineResponsible for co-ordinating the server side execution of the Pattern Pages and the interaction of the pattern page with the underlying business templates.
Business TemplatesThe templates are responsible for providing the core business functionality. There are a number of templates, each specialising in a different are of functionality. A clients requirements are typically satisfied by combining the functionality of several templates.

By themselves the elements are a set of very powerful utilities. Combined together they provide an ideal framework for delivering sophisticated, feature rich web applications. It is the role of the integration partner to utilise these resources to satisfy the business requirements of their clients.

Whitebeam recommend following a good design process when developing web applications. A good process will allow the integration partner to correctly identify customer requirements, implement those requirements and ultimately satisfy the business requirements of their clients.

Administering Client Applications

Integration Partners interface with the Whitebeam system using the Site Management Application (the "dashboard"). This provides a browser based user interface to maintain Clients, their URLs and to control their sites.

An application comprising ordinary static (.html/.htm) and dynamic (.rhtm) pages is transferred to a staging area on the Whitebeam system using conventional FTP. When the FTP connection is terminated a background task moves the uploaded files to a "test instance" of the Client's site. This site is a completely separate from their production site with a different URL used to test the new version of the application without affecting the live site. The dashboard also gives the Partner the ability to copy the live site data to the test instance so that real data can be used to give the best test coverage.

When the Partner and Client are happy with the new version of the application it can be made "live" through a command available from the dashboard.

Source Code

A Whitebeam application generally consists of a set of "source" files that together provide the desired look, feel and functionality required to support a client. These files are contained in a hierarchical file structure decided on by the Integration Partner. The site comprises any combination of static web pages, Whitebeam Pattern Pages and various 'other' files (e.g. bitmaps and gifs).

An application may also have data pre-loaded onto the Whitebeam database along with dynamic data that is captured in operational mode. Such data may include any type of file (from the file system or generated) which is treated as binary data (up to a size of 100K initially) by the Whitebeam system.

Writing a Whitebeam application requires technical skills in:

SkillDescription

HTML

Hypertext Mark Up Language for formatting web presentation pages.

JavaScript

An interpreted programming language with object-orientated capabilities that is used extensively to create dynamic HTML content. JavaScript is run on browsers and also, on the Whitebeam system, on the server (see below).

Whitebeam JavaScript

A JavaScript-derivative language is defined to provides access to the Whitebeam Object Model (ROM), and in turn, to the exported interfaces of Whitebeam Templates

Whitebeam XML Mark-up

A collection of Whitebeam defined XML Mark-up that augments the standard HTML with special tags and attributes that are interpreted by the Presentation Engine. The mark-up tells the Whitebeam System what data to send to the client.

Pattern Page

A pattern page is a Whitebeam source file that has a very similar format to a static HTML source file but with the addition of some Whitebeam-specific XML tags and (optionally) Whitebeam JavaScript. It can also be written using any basic text editor.

A simple example of a pattern page would be:

<html>
  <head>
    <title>Example Page</title>
  </head>
  <body>
    <rb:script>
      rb.page.write('<p>Hello'+' '+'world</p>');
    </rb:script>
  </body>
</html>

When a request is made to serve this pattern page, the Whitebeam Presentation Engine will, in this case, automatically parse, generate, and deliver to the browser the HTML presentation page:

<html>
  <head>
  </head>
  <body>
    <p>Hello World</p>
  </body>
</html>

XML and Server Side JavaScript

A web site design generally consists of many different types of file. Most of these are simply requested by the client, located by the server and returned to back to the client. This items are 'static' meaning they never change, except at the hand of the designer. Once the files have been placed on the web server they are delivered unchanged to the client browser. Examples of static resources include everything you'd expect to see on a static site - images, documents, HTML source etc.

A Whitebeam Pattern Page is an active element. Instead of being forwarded transparently to the client the page is given to the Presentation Engine. It is the responsibility of the Presentation Engine to open the Pattern Page and execute the 'code' within that page to generate the data to be sent to the browser.

A Pattern Page has the following characteristics:

 Description
.rhtm filename extensionAll Pattern pages must have a filename extension of '.rhtm'. This is the means by which the Whitebeam System knows the file contains a Pattern Page and must be routed via the presentation engine.
XML structureAll files are expected to contain conformant XML mark-up. The contents will be processed first by the Presentation Engine and then by the browser. The XML in the file is a combination of the following:
Client Side XHTMLBasic web page content to the sent to the client. Note that the Whitebeam System requires valid XHTML mark-up, although it will do its best to process non-conformant code (such as older HTML) the best results are to be achieved by following the XHTML guidelines.
Server Side XMLSpecial XML Mark-up that is understood by the Presentation Engine. This mark-up is replaced by the presentation engine before the generated page is sent to the client. This mark up - a combination of XML tags and XML attributes - effectively form a sequence of instruction for the Presentation Engine on how to generate the dynamic content of the Web Page. Whitebeam have implemented a number of pre-defined tags (all have the form rb:something) but the developer can, in fact, define his own XML tags and what the Presentation Engine does when it encounters them.

When a request is received for a dynamic '.rhtm' file the Presentation Engine executes the Pattern page and replaces the server side code as appropriate.

The Presentation Engine is basically an XML processor closely coupled with a JavaScript interpreter. The XML processor is fairly "lenient" towards HTML but in general Whitebeam recommends that all pages conform to the XHTML recommendations.

An example of Whitebeam XML mark-up is <rb:script> tag (and its corresponding closing tag </rb:script>). This marks a block of server side JavaScript. Another example is the <rb:include src="someFile" /> tag that allows a pattern page to include content from another file (the included file can, in fact, be any legal XML document so there are many possible ways to use this feature). All the Whitebeam tags are fully documented elsewhere.

There are several XML rules to remember when constructing a pattern page:

  • XML is structured so the contents between starting and ending XML tags can only be valid if it follows the defined XML DTD. For instance the <rb:script> tag can only contain server JavaScript, no other XML or HTML.

  • XML tags can be closed by including a "/" before the closing angle bracket but although legal it renders some Whitebeam tags ineffective e.g. <rb:script/> is legal but will not do anything!

  • XML tags can be placed within HTML provided the starting and closing tags are within HTML block tags e.g. <p><rb:script>..program..</rb:script>..something..</p> is legal but <p><rb:script>..something..</p></rb:script> is not.

  • XML attributes (such as rb:eval) can be placed within any XML/HTML tag and get "executed" by the Presentation Engine. The result is a substitution of the original XML with the output of the evaluation.

  • The syntax of statements must follow XML rules. In most cases this is straightforward and intuitive but one exception is the way to encode special characters within tags. You cannot escape by preceding the character with a \ but have to use the XML syntax of %nn for a character or the &quot; etc. mnemonics. For instance to place a quoted string within two other levels in an <rb:eval> tag would look like this: <rb:eval expr="if (isUser) rb.page.write('<input type=&quot;submit&quot; name=&quot;update&quot; >');" />

  • No Whitebeam tags can be placed within JavaScript either on the server or client side. On the server side there are Resource Object Model (ROM) equivalents of appropriate tags (e.g. rb.page.redirect() rather than rb:redirect src="dfghsd"/>). On the client side to generate client JavaScript you have to write the code out using rb.page.write () calls e.g.

rb.page.write("<script language='JavaScript'>\n<!--\n");
rb.page.write ("var isUserMsg = "+isUserMsg+";\n");
rb.page.write ("var userMsg = "+userMsg+";\n");
rb.page.write("//--></script>\n");

Structuring an Application

If you have a background in structured programming and object oriented design techniques producing an application that uses a browser interface can leave you cold. The issue is the way to structure the application when the device used to control program flow, the hyperlink, is essentially a "goto". Whitebeam recommend a specific structure and have designed some key features into the system to support it.

A requested page often has to do more than just present data and a few hyperlinks e.g. it might have to be a form in order to submit parameters back. The URL to which the page is then submitted may have to do some server processing and then present a new page back to the originator. However it might need to present a different page depending on the parameters submitted. This can sometimes be achieved by dividing the submitted page into a number of separate forms, each form with a different submit URL. However this is not always possible and anyway, typically leads to duplicated code.

To avoid this problem Whitebeam recommends that in most cases the code that processes a form is in the same page as generated the form. i.e. the form is submitted to itself. This makes it much easier to structure the application, code variable names etc. You are probably asking how, if a form submits to itself, do you put up a new, different form or page? The Whitebeam system supports a redirect mechanism, available either through an XML tag:

<rb:redirect src="somewhere" />

or alternatively through the ROM:

rb.page.redirect("somewhere")

This causes the presentation engine to discard all page output from the currently executing Pattern page and start again with the redirected Pattern page. Note that a redirect is not a goto. It is structured in that execution of the original page will continue after the redirected page is processed. Although no page output will be produced, any side effects of program execution will still take place (e.g. you could have a piece of code on the original page that "tidied up" after any redirect).

Another, associated mechanism supported by the Whitebeam system is the included page (<rb:include src="something" /> tag). The included item does not have to be a complete page, any valid XML document is acceptable. The include mechanism also enables sections of the named file to be selected as specified by an id attribute; those sections in the included file being identified by a rb:id attribute in the tag name.

Form Data

All applications will use forms to input data from a user's browser and the Whitebeam system provides a very easy mechanism with which to read the data into an application. The form data can be submitted with a GET or a POST (or indeed the input could be made in the form of a "manual GET" by means of URL parameters such as www.redbourne.com/input.rhtm?count=342); in either case a call to the rb.page.formdata() method gets the parameters. These parameters become properties of the object returned, the name being the name of the parameter, with a value set to the parameter value. Automatic "unescaping" of encoded parameters is performed by the method to make manipulation as straightforward as possible.

As an example consider a form that POSTs two pieces of data: 1) a text entry box and 2) a submit button:

<html>
  <head>
    <title>Form Example</title>
  </head>
  <body bgcolor="#FFFFFF">
    <form name="form1" enctype="multipart/form-data"
          method="post" action="process.rhtm" >>
      <input type="text" name="textfield">
      <input type="submit" name="Submit" value="Submit">
    </form>
  </body>
</html>

The process.rhtm pattern page that processes this form could look like this:

<html>
  <head>
    <title>Form Processor</title>
    <rb:script>
      var formdata = rb.page.formdata();
      var suppliedText = formdata.textfield;
    </rb:script>
  </head>
  <body bgcolor="#FFFFFF">
    The data supplied was <rb:eval expr="suppliedText"/>
  </body>
</html>

Some key points about form data:

  • text input parameters are always sent by a GET or POST although their contents will be empty (i.e. formdata.textItem == "") if the user has not entered any data

  • button input parameters (submit, radio etc.) will only be sent when the item is selected otherwise they will not be present (i.e. formdata.buttonName == null)

  • select input parameters ( menu, list) are only sent if selected. If the select is MULTIPLE and the user selects more than one option on the form the contents will be made available as an array (i.e. formdata.selectName[i] where i = 0, number of items selected - 1)

  • file input parameters are always sent although their contents will be empty if the user has not selected any file (i.e. they have no length formdata.fileName.length == 0). Note that the Whitebeam system defines a special File type that has a number of special methods.

Session Data

A very important and useful feature of the Whitebeam system is the mechanism it provides for context tracking. Context tracking is the ability to identify a series of requests as coming form the same user browser session (no inherent mechanism is designed into web browser protocols). It is essential to have such a mechanism when trying, for example, to create a user "shopping basket" that remembers items that have been added to it as a user traverses a website. In the Whitebeam system context tracking is provided by "session data" and the ability to add "session markers" to URLs and forms (necessary to track context if a users browsers has cookies turned off).

If you are a programmer, session data is like having a static global variable (in the form of a container for JavaScript objects) for your set of Pattern pages. The data can be read, modified and then saved again from any Pattern page. Note however that the session data is volatile - it "evaporates" after about 30 minutes so the very first thing you need to do before you use it is check it for validity.

First time you read session data (e.g. var sData = rb.page.session.read();) there will be no user data present - the assigned object has no user assigned properties (note that it is not unassigned and it does not test equal to null, this is because the system uses "hidden" properties in the session data). You can then add any number or type of JavaScript objects to the session data such as in this example:

sData.item = new Object();
sData.item.colour = "blue";
sData.item.number = 42;

Finally the session data is saved (e.g. rb.page.session.write(sData);) so that it is available from other pages.

If you examine the sample applications provided by Whitebeam you will see that extensive use is made of session data. It is used variously to collect information from a number of linked forms, hold item details to associate a form response to the item displayed and to simply record state information. You will also notice two useful programming techniques used:

  • To prevent clashes in session data object names each set of functionality sets object names one level under the top level e.g. sData.editcat.something rather than sData.something. The main reason behind this is that a user could have multiple browser windows open at the same time each looking at a different piece of the application. A session applies to each browser instance not each individual window.

  • At the start of each page that uses session data a test for validity is made (by testing for a specific object held in the session data along the lines of sData.item == null ). If the data is invalid a redirect is made to a suitable page telling the user of the fact and restarting the page sequence. (Typically certain data will also be initialised to prevent errors from side effects - a redirect is not a "goto", see the rb.page.redirect() method for details).

See the technical note for more details on session data.

Access Control

The Whitebeam system makes it very easy to restrict access to certain pages (or subsections of pages) of an application by using <rb:authenticate> tags in conjunction with the Contacts template. In the simplest use of the feature when a user attempts to access the protected page the browser will prompt him to enter a username and password. If the username and password is valid for the group specified in the authenticate tag, access will be allowed. For example a page could be protected as follows

<rb:authenticate domain="Redbourne example"
                 community="user" mandatory="no" >
  <html>
    ...the rest of the page
  </html>
</rb:authenticate>

The domain is simply a text string that is displayed by the browser in the login form automatically displayed. If the browser supplies an 'authorization' header then the browser provided username and password is validated against the specified 'community'. The community parameter specifies a unique name (held in the contacts template as a uName) which may be a Community, an Individual or an OU (Organisational Unit) held in the database. If mandatory is 'yes' then the browser provided username and password must match against a member of the specified community. If it does not match then the section of the page contained within the tag is not executed. If mandatory is 'no' then the page is executed anyway allowing the pattern page to programmatically deal with the error.

An example of the use of mandatory set to no would be a page that requires a username and password but that presents the user with a self registration page if the user does not have a logon. Authorisation status can be checked by comparing rb.security.auth.status()="AuthOK" and appropriate action taken.

Note: A Whitebeam library is available to provide alternative access control methods, seen on many Internet sites. Details of this can be found in the Tutorials section

Templates

Whitebeam templates provide specific "pre-built" functionality that enable developers to build bespoke applications quickly. The templates are designed as interlocking components which are made available to developers in the form of the Resource Object Model (ROM). The ROM is exposed through the Presentation Engine to the server side XML and JavaScript. An on-line reference provides details of all method calls and data structures.

Some fairly complex data structures are used to interface with the templates but typically very few properties are mandatory, many are optional or default to a value. A default value means that the property will be set to the stated value if a user does not supply a value. An optional value means that the current value will be used if the user does not supply a value. In both cases "not supplying a value" means not defining a property in the corresponding object data structure.

The templates generally have a "back-end" connection to a database system which they use to securely store application data. The templates provide an object-oriented view of this database and generally use/provide two important mechanisms described below.

Metadata Fields

Many Whitebeam templates include "metadata" fields that allow the data objects provided by the templates to be extended by the application designer. A metadata field is a JavaScript object container (similar to the session data container) that can contain any arbitrary JavaScript object. For example individual and OU objects in the Contacts Template support the customData metadata field that could be used to store network information alongside their name and telephone number:

user = new Object();
user.customData = new Object();
user.name = "Tom Jones";
user.phone = "0870 1664400";
user.customData.IPadd = "121.34.55.67";
user.customData.floorSocket = "A47";
user.customData.patch = "3-23";

Most template search methods support searching the metafield contents as a whole, individual developer-defined sub-objects or properties cannot be isolated and searched for on their own.

Note that, unlike session data, the system does not use hidden properties of metadata fields and so an empty metadata field (i.e. no developer defined properties set) will test equal to null.

Iterators

Many Whitebeam templates use "iterator" objects. These are used to return collections of objects when the size of the collection returned is indeterminate but could be very large e.g. the results of an item search from the Catalogue template. An iterator object is like any JavaScript object except it has one very important method defined - getNextRow(). Making this call changes the object's contents to represent the next sequential object in the collection. An example of the use of an iterator is shown below. This code fragment gets an iterator object representing all users within a particular community (Contacts template):

var user = rb.contact.whosIn(community);
while (user.getNextRow()) {
    do something;
}

Note that the method call to return an iterator only initialises the iterator object, getNextRow() has to be called to get the first item of the collection. If the iterator object is null then the end of the collection has been reached (or if the first call to getNextRow() returns null the collection is empty).

Files

Two types of file access are supported within the Whitebeam system, the File template provides for file storage and retrieval within the database and the special method calls provide read-only access to the web server file system.

The File template provides facilities to read and write files up to 100K bytes in size together with associated information such as a name and description. This template is available in its own right and also other templates make use of the file template, for example to hold images of products stored as items within the Catalogue template. A special Binary JavaScript object type is provided by the Presentation Engine to enable the files to be manipulated programmatically. For example the following code loads a file form variable into a local Binary object:

var parameters = rb.page.formdata();
var binaryFile = parameters.file0;

The Binary object has some methods defined for it such as mime() which sets or reads the mime type of the file (note that the File template stores Binary objects so implicitly holds the mime type of the file being manipulated).

rb.page.write(binaryFile.mime());

The load() method of the binary object lets you load up a file from the file system into the object. Typical uses for this could be to secure the download of, say, a "pdf" document. By wrapping the access to the document in an authenticated Pattern Page direct access is prevented. See the widgets section of the sample applications for an example of how to do this.

Debug Support

As with every software design the key to easy debugging of a Whitebeam application is to get the application design complete before committing to write any code. Server-side JavaScript is generally much simpler than Client JavaScript: there are no version issues, no browser compatibility issues, DOM or event handling issues to worry about. However - some bugs will still appear in the server-side application. The Whitebeam system provides several facilities to make it easier to find these faults.

First and foremost is the 'test instance' - a complete shadow of the main site that is however independent. You can use this both to debug new versions of applications and to debug issues found in the field. The test instance is distinguished from the operational application in the following ways:

  • Accessed through a separate URL.
  • Uses a separate set of 'test' data in the templates - the live data can be copied to test area in order to seed the data.
  • The Presentation Engine is more thorough in testing the application and will detect mark-up errors in the page that are ignored in the operational site.
  • If an error is detected - the output from the page is discarded and a debug report produced instead.

In the test instance of the site all errors are reported to the requesting browser - these could be JavaScript errors, run time errors or template interfacing errors (e.g. a value out of range).

To help narrow down bugs - the presentation engine provides a debug output facility: rb.debug.write. Basically this allows the implementor to record debug messages -for example intermediate values. This messages are discarded if the page generates no errors. If errors are detected then the contents of the debug buffer are added to the output stream sent to the browser. Alternatively the debug output can be manually inserted into the output stream using the <rb:insertdebug...>.

In production mode all error reporting is suppressed (apart from web server standard 404 page not found etc. errors). If a run-time error is encountered by the Presentation Engine it ignores it and carries on parsing the Pattern page sending the potentially incomplete page back to the requesting browser.

Web Server and File Locations

With one exception Whitebeam allows any directory and file arrangement to be used on a Client virtual server. The server will not display a directory listing under any circumstances and will look for index.rhtm, index.html, index.htm, default.html and default.htm files to display in that order. Any file can potentially be served on a normal or encrypted SSL service. To indicate that a particular page should only be served if it is requested via "https" a <rb:protect /> tag has to be present at the top of the page.

The server is also configured not to serve directly any content from a special predefined top level directory named "rbhidden" (or any of its subdirectories). The contents of the directory are still available to any running Whitebeam JavaScript so can be manipulated programmatically (see the example in the Files section).

General Tips and Hints

Copying Data Structures from Server to Client Domain

If you want to generate a client-side JavaScript data structure which is an exact copy of a server-side data structure use the toSource() method. This method works on any server-side JavaScript object and turns the object into its object literal syntax equivalent. For example, here a piece of Whitebeam script generates a piece of client JavaScript that produces a copy of the server JavaScript object and its values:

rb.page.write("<script language='JavaScript'>\n<!--\n");
rb.page.write ("var clientStruct = "+serverStruct.toSource()+";\n");
rb.page.write("//--></script>\n");

There is no real equivalent if you wish to copy a client data structure back to the server after some user modifications (most client browser JavaScript implementations do not support the toSource() method). Therefore you have to rely on the form interface and send back individual data items (loosing any object structure that may have existed). The best way round this is to store the original data structure in session data when the form is initially generated and then modify it based on the changed variables posted back.

Variables

Don't forget that JavaScript Date values are in milliseconds.

Keep variable names consistent (i.e. client-side, server-side and ROM).

Generating Values to use in HTML

The cleanest way to generate values in HTML from Whitebeam script is to use the rb:eval="attribute#expression" attribute and the <rb:eval expr="expression"/> tag within the HTML on the server. Expression can be anything from the ROM, functions or variables. For example, the following code inserts the name of the person that has logged onto the page as a cell in a table:

The following is a sample function to be called from within a tag:

<rb:script>
  // Simple function to get the name of the person who successfully
  // accessed this page
  function activeUser() {
  var me = rb.contact.individualInfo(-1, rb.security.auth.username());
    if (me == null) return "";
    else return me.name;
  }
</rb:script>

This is the HTML that uses the function above:

<td> Hello <rb:eval expr="activeUser()"/>, welcome to site administration </td>

Undefined and Null, Testing for False

Testing for undefined can cause some pitfalls for the uninitiated and initiated alike! The undefined value does test equal to null but this is not the same as saying that it is "false". One problem is that !undefined is still undefined so you cannot do the following reliably (a test based on formdata parameters being supplied) if one of the conditions you are testing for is undefined:

if (parameters.extra&&!parameters.add)

testing for not equal to null does work:

if (parameters.extra&&parameters.add!=null)

Testing for the presence of parameters in formdata can be done as in

if (parameters.add)

if the form data includes the parameter "add" then the test will be true.

Whitebeam release 1.3.36
(loadtime : 7ms)