Riverwatcher Active Content Environment

RACE Documentation:

RACE Flow Model

The RACE Engine is a modular component of your web server. When a web browser requests a RACE page from the web server, the web server loads the page and then pre-processes it with the RACE Engine before ever sending any data to the client's web browser. The RACE Engine processes the file linearly, starting at the top of the page and proceeds until it reaches the end. Any data that the RACE Engine does not recognize is buffered so that it may be sent to the web browser after processing the page. If RACE recognizes a RACE tag or variable, the appropriate action takes place. a RACE tag or variable reference will have one of the following effects on the data which is being added to the buffer:
  • No output will be added to the buffer. This would be the case for a <define> tag or <asis> tag.
  • Part of the file being processed may be omitted entirely. This may occur if a database query produced no records, or if a conditional operator like <if> is encountered.
  • Part of the file being processed may be repeated multiple times, such as the template in a <database> tag, <for> tag or <while> tag.
  • Data may be pulled from an outside source, as with the <include> tag or invoking a user defined tag.
The interaction between the Web Browser, the Web Server, and RACE can be visualized in the following way:

Diagram of how RACE works

A full understanding of this model is not necessary to take advantage of the many features of RACE. It will, however, help in following and debugging the tags which take advantage of templates and conditionally alter the flow of processing.

A key difference between RACE and all other server-side scripting environment is that the RACE execution context is the entire RACE page. Where as in other server-side scripting languages the execution context exists within a script block. In ASP such script block is denoted by "<%" and "%>" and in PHP "<?php" and "?>". Because RACE is a true template language, it does not require a separate "output" statement to send data back to the browser.

For example, the following ASP script connects to a database and outputs the results to a browser:

Set OBJdbConnection =Server.CreateObject("ADODB.Connection")
OBJdbConnection.Open "catalog"
SQLQuery = "Select id, description FROM Models"
Set RSModels = OBJdbConnection.Execute(SQLQuery)
Do Until rsModels.EOF
Response.Write (rsModels("ID") & "<BR>\n" & rsModels("Description") & "<BR>\n")

The same code in PHP:

$db = mysql_connect("localhost","root");
$result = mysql_query("SELECT id, description FROM Models",$db);
printf("%s<br>\n", mysql_result($result,0,"id"));
printf("%s<br>\n", mysql_result($result,0,"description"));

The same code in ColdFusion looks like this:

<cfquery name="rsModels" datasource="catalog ">
select id, description from Models
<cfoutput query=" rsModels ">#id#<BR>\n#description#<BR>\n</cfoutput>

To do the same in RACE:

<database dsn="catalog" query="select id, description from Models">

This tighter level of integration of RACE scripts and the HTML data not only results in shorter code, but also makes RACE scripts more intuitive to conceptualize and easier to program.

RACE Data Types

Within a RACE document, the following data types may be employed:
  • standard (scalar) variables
  • arrays or lists
  • hashes
  • database fields
  • prefix variables
  • tags
  • macros

Standard variables may contain numeric values or arbitrarily long character sequences. Numeric values are stored as character strings and are converted to integer or floating point numbers as needed. If a variable does not consist of numeric components, it will evaluate to 0 if it is referenced in a context requiring a numeric value.

Standard variables are normally referenced in a RACE document as <$variable> where variable is the name of the variable. If a standard variable is referenced as <$$variable>, then the value of <$variable> is treated as the name of another standard variable or database field and its value is returned. For example, if <$a> has been defined as 'b', and <$b> has been defined as 'c', then <$$a> is equivalent to <$b>, and would return 'c'. If <$b> were currently undefined, then RACE would attempt to return the value of a database field labeled 'b' if the current context were within a DATABASE tag. Arrays, sometimes referred to as lists, are variables which contain multiple values. An array in RACE is referenced as <@variable>, and may contain zero, one, or many elements. Each element can be a numeric value, or a character string. See the <DEFINE> tag for an explanation on creating and accessing array elements. It is also worth noting that a form submitting its data to a RACE page will have it's Checkbox elements stored in RACE arrays, as well as any input type which defines multiple values for the same element name (for example, multiple hidden elements with the same Name attribute). If you reference a RACE array variable using the scalar format, i.e, <$array>, you will get the first element of the array.

Hashes are useful for storing key-attribute value pairs. For example, a hash of phone number hash stores the name and phone number value pairs so that you can get a phone number when you supply the name as the key. Assuming Joe's phone number is 555-1234, <$phone{'Joe'}> will return 555-1234. Another way to access the phone number for joe is to use the following expression, <$phone.Joe>. Database fields exist only within the template of a <DATABASE> tag. The fields are referenced as <#field> where field matches one of the fields indicated by the select query just issued. The template of a <DATABASE> tag is looped through for each record returned, so the first time through, <#field> will evaluate to the entry in the first record returned, the second time through it will evaluate to the second record returned, etc. Database fields do not exist once the context is closed (ie, the </DATABASE> tag is encountered), so any information which must be used outside of this context will have to be stored in a standard variable before closing the database context. Database tags can be nested. If a field exists in the inner database tag, then that field will overshadow the field of the same name in the outer database tag.

Prefix variables are a special case of standard variable. These variables are often used in shopping basket type situations and are named, not by a unique name, but by an identifier and the data related to the particular instance of the prefix variable. They have the form 'identifier:value1:value2:value3:'. The identifier identifies the particular group that a given instance is a member of, but the specified values will be different for each particular instance. They provide a unique way to handle dynamic or array bound data without using arrays. See the explanation of the <FOR> tag and the appendix dedicated to prefix variables for a more complete explanation.

Tags can either be user defined or internally defined. The internally defined tags are listed later in this document. Tags are case insensitive, and user defined tags can override the internally defined ones. Currently there is no way to access an overridden tag.

Macros are functions that you can call on a variable. Invoking a macro is very similar to invoking a method in object-oriented programming. There are built-in macros, such as add, and any tags you define can also be used as user-defined macros. For example, assuming the variable <$n> contains the value 1, <$n.add()> will increment it by 1.

RACE Documentation

Copyright 2009 Riverwatcher, Inc. Hosting by Riverwatcher Studios