IntroductionWhitebeam 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". 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: Entity | Responsibilities |
---|
Web Browser | Responsible 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 Engine | Responsible for co-ordinating the server side execution
of the Pattern Pages and the interaction of the pattern page with the underlying
business templates.
| Business Templates | The 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 ApplicationsIntegration 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 CodeA 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: Skill | Description |
---|
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 PageA 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 JavaScriptA 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 extension | All 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 structure | All 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 XHTML | Basic 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 XML | Special 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 " 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="submit" name="update" >');"
/> 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 ApplicationIf 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 DataAll 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 DataA 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: See the technical note for more details
on session data. Access ControlThe 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 TemplatesWhitebeam 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 FieldsMany 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. IteratorsMany 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). FilesTwo 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 SupportAs 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 HintsCopying Data Structures from Server to Client DomainIf 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. VariablesDon'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 HTMLThe 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 FalseTesting 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&¶meters.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. |