| contents | queries | |
| configuration | templates | |
| expressions | sessions | |
| databases | data entry | |
| passwords | ||
| license | support |
Tags
Displaying single records
Directives
Displaying multiple records
Conditional display
Lists
Unique lists
Totals and averages
European languages
baserunner templates are HTML files that contain directives and tags that baserunner parses to produce the output sent to the user. Tags are elements that are replaced by data or some other value. Directives, which are included as HTML comments, set off blocks of HTML code for some special processing. Template files may have any extension. A template must, once the tags and directives have been processed, produce a standard HTML file.
Any HTML editor may be used to produce the template files, but you will need to go into the raw HTML code to add many of the tags and directives. If you are using a WYSIWYG editor, you need to take special care when adding expressions to your template. Many of these editors will "fix" your code, and render the expression meaningless. The problem is most evident if you add expressions that contain symbols like ">" or "<", or double quotes, or in statements that need to include white space. It is probably best to simply complete your design with dummy data, and once you have the template looking the way you want, use a text editor to insert the tags that cause the problems. FrontPage does have an option to add "HTML Markup" that is not checked and reformatted by the editor, but it doesn't work very well. Other WYSIWYG editors probably have a similar feature. Notepad is always a good choice.
baserunner templates permit you to display data and other variables in a variety of ways. You can display lists of data, single or multiple records, totals of numeric data, and unique lists. You can also specify blocks of code that will only be shown if a filter is in effect (or not), or if an expression is true.
While templates may be stored in any directory, once they are parsed and sent from baserunner to the user, the server treats them as if they are files in the root web directory. Any links (e.g. to images with a relative link) should be included as if the file is located in the root directory.
By default, all tags used in a template are strings enclosed in curly braces, {tag}, and the documentation uses that convention. But, you may change the characters that enclose tags by adding the variables _tagstart and _tagend to your configuration file (or, if the change is only for a single page, send those variables from the command line or a form). The value for _tagstart and _tagend must be the same length, and must contain different strings. Generally, you'll want to change these characters if you have a template that uses "{}" for purposes other than baserunner tags, e.g. JavaScript or a style tags.
Most tags will consist of data expressions that are replaced by data taken from the current record in the database. The simplest form of a data expression is just the name of the field: {field_name}. Expressions are standard xBase language statements that can get fairly complex. Any tag that cannot be replaced with data, will be removed. Please see the expressions page for details on the syntax of xBase expressions.
These are the most commonly used expressions for displaying data:
| Memo fields | {memo_field}
|
| Character fields | {chr_field} {trim(chr_field)}
|
| Numeric fields | {str(num_field, 10, 2)}, {str(num_field)}
|
| Logical fields | {logic_field}, {IIF(logic_field=.T.,"True ","False")}, <input type="checkbox" {IIF(logic_field=.T.,"checked"," ")}>
|
| Date fields | {date_field} {dtoc(date_field)}
|
Other tags include:
| {count} | This variable displays the number of records in the database or the number of records that are included in the current filter set. | ||
| {rand} | This tag displays a random number. | ||
| {setdisplay} | This tag displays the current value of the _display variable (the number of records shown when the <!--repeat--> directive is used). | ||
| {session} | This tag displays the name of the user's session. | ||
| {filterexp} | This tag displays the current filter (query) expression. | ||
| {sortexp} | This tag displays the current sort expression. | ||
| {longtime} | This tag will display the current system time as a long integer. Under some circumstances this may be more useful that the time() expression. | ||
| {server_variable} | Any server variable that is available to baserunner may be
displayed. These include (among others):
The results returned by any of the server variables will be dependent on the configuration of the particular server. |
||
| {_variable} | A tag can refer to any variable in a configuration file (or passed to baserunner by a form). These tags must be prefixed with an "_", i.e., {_myvariable}. Such user-defined variables are useful in passing specific values from one page to another. A named variable may also be used to insert an expression into a conditional expression directive. |
baserunner processes tags that refer to a variable, e.g. {_variable} before any others. Because of this, tags that refer to a variable may be included within other tags. These interior tags must contain only a variable name (i.e. prefixed with an underscore, "_"). For instance, if you have a variable that contains a number, you could set up a tag like:
{str(field+{_variable},10,0)}
In this case the value of _variable would be added to the value of the numeric field "field", and the result would be displayed in the output. The interior tag {_variable} is processed first, so when the exterior tag is processed, the tag is read as:
{str(field+200,10,0)}
(assuming, of course, the value of _variable is 200). Such nesting of tags may only be one layer deep. Only tags that refer to variables in the format {_variable} can be nested.
Any data expression tag contained in a template that is not enclosed in a list block, a unique block, or a repeat block will be replaced with data from the current record. If you open a template that displays a single record when baserunner starts, the first record in the database (or in the current query) will be displayed. Navigation actions will move through the database one record at a time for a single record display.
The current record is: {ltrim(str(recno()))}
Field 1: <h1>{trim(chr_field)}</h1>
Field 2: {dtoc(date_field)}
Field 3: {memo_field}
<form method="GET" action="/cgi-bin/baserun.exe">
<input type="hidden" name="_ses" value="{session}">
<table>
<tr>
<td><input type="submit" name="_act" value="Top"></td>
<td><input type="submit" name="_act" value="Back"></td>
<td><input type="submit" name="_act" value="Next"></td>
<td><input type="submit" name="_act" value="End"></td>
</tr>
</table>
This simple example displays the contents of three fields and shows the current record number. The navigation actions are presented in a form.
The current record is: {ltrim(str(recno()))}
Field 1: <h1>{trim(chr_field)}</h1>
Field 2: {dtoc(dat_field)}
Field 3: {mem_field}
<a href="/cgi-bin/baserun.exe?_ses={session}&_act=top">[ Top ]</a>
<a href="/cgi-bin/baserun.exe?_ses={session}&_act=back">[ Back ]</a>
<a href="/cgi-bin/baserun.exe?_ses={session}&_act=next">[ Next ]</a>
<a href="/cgi-bin/baserun.exe?_ses={session}&_act=end">[ End ]</a>
This example uses normal links for the navigation actions. Both examples here omit the _tar variable since the same template will be called for each record. If you are putting together an application that uses several templates, it may be a good idea to include the _tar variable anyway--If a user arrives at this page via the "back" button on his browser, baserunner might have a different idea about what the current template is. In this case the call would be:
<a href="/cgi-bin/baserun.exe?_ses={session}&_tar=[this template]&_act=top">
[ Top ]</a>
Of course, adding the navigation actions is not required. If for instance, your single record display is used to show details about a record selected from a multiple record display, you may wish to simply provide a link back to the calling page:
<a href="/cgi-bin/baserun.exe?_ses={session}&_tar=[calling template]">
[ Go Back ]</a>
When you wish to display multiple records, lists of data, or conditionally display data, you need to add baserunner directives to your template. Directives are entered as HTML comments:
| <!--directive--> HTML code <!--enddirective--> |
Directives are used in pairs that set off blocks of code which are processed separately from the rest of the template. Since all comments need to be checked to see whether they contain directives, you should avoid adding any unnecessary HTML comments to your templates. When a directive name ends in "X", that signifies a name that must contain the beginning string (e.g., list) and have a unique identifier added, replacing "X", e.g., list1, list2, etc.
| Directives | Description |
|---|---|
| <!--repeat--> <!--alternate--> <!--endrepeat--> |
Code contained within a repeat block is displayed for X records (determined by the value of the _display variable. The alternate directive is optional. If it is used, every other record will be displayed using the code following alternate. |
| <!--listX--> <!--endlist--> |
Code contained within a list block will be displayed for every available record. Each list must have a unique name. The list may be sorted by adding a variable with the same name as the list (with an underscore added to its beginning, i.e., _listX) to the configuration file. This variable contains a valid expression. |
| <!--uniqueX--> <!--endunique--> |
Code contained within a unique block will display each unique value in the available records. Each unique list must have a unique name. A variable with the same name as the unique list (with an underscore added to its beginning, i.e., _uniqueX) is required. This variable contains a valid expression. This expression is used to test each value to determine whether it is unique. |
| <!--totalX--> <!--endtotal--> |
Numeric expressions contained within a total block are replaced by the value of the sum of the expression for all the available records. |
| <!--averageX--> <!--endaverage--> |
Numeric expressions contained within an average block are replaced by the average value of the expression for all the available records. |
| <!--expression--> <!--else--> <!--endcondition--> |
The opening directive of a conditional display block is a logical expression. That expression is evaluated, it it is true, the code is displayed. If the optional <!--else--> directive is used, the code following the else directive is displayed if the condition is false. |
| <!--filter--> <!--endfilter--> |
Code contained within a filter block is displayed only when a filter is in effect for the database. |
| <!--nofilter--> <!--endnofilter--> |
Code contained within a nofilter block is displayed only when the database in unfiltered. |
A block of HTML code contained within the pair <!--filter--> <!--endfilter--> will be displayed only when a filter is in effect. Similarly, a block of code contained within the pair <!--nofilter--> <!--endnofilter--> will be displayed only if a filter is not in effect. Particularly when displaying lists that could become very large if applied to the entire database, the use of a filter block is important. The filter block is processed before any tags or directives.
<!--filter-->
The current query is: {filterexp}
<!--endfilter-->This code would display the current query statement only if a filter was in effect. Otherwise, the entire block would be deleted from the display.
You may also conditionally display HTML code based on a logical expression (any expression that evaluates to either true or false). A block of HTML code contained within the pair <!--expression--> <!--endcondition--> will be displayed only when the expression evaluates to true. You may also add an <!--else--> directive between the pair. If the <!--else--> directive is present, the HTML code that follows the directive will be displayed if the condition is not true. Conditional blocks are evaluated at the same time as data tags. These conditional blocks are similar to using iif() expressions, but offer more flexibility.
In place of the expression that begins the conditional display block, you may use a named variable (prefixed with an underscore, "_". In this case, the expression used for the conditional display will be read from the variable. This variable must exist in the application configuration file or be passed through a form or the command line. Using a variable offers the possibility of changing the dynamic display directive dynamically in your application.
The expression used to begin a conditional display block may contain baserunner tags that refer to variables, e.g. {_variable}. No other tags are permitted within the expression. For instance, you may use an expression like:
<!--field="{_variable}"-->
where the tag {_variable} would be replaced by its value before the expression is evaluated. If you wish other information in a conditional expression, you will need to assign it to a variable: for instance, if you wanted to use the session name as part of a conditional display expression, you would need to assign it to a variable _sname={session}, then use {_sname} as part of the conditional display expression.
Do not confuse the two distinct uses of variables for conditional display directives. The first uses just a variable name and gets the entire expression from a variable. The second uses a variable tag within a conditional display expression. These tow formats may not be mixed together.
Conditional display blocks may not be nested, i.e. they may not contain other conditional display blocks.
<!--log_field=.T.-->
HTML code that is only displayed if the logical field "log_field" is set to true.
<!--endcondition--><!--"@"$chr_field-->
HTML code that is only displayed if the character field "chr_field" contains the character "@".
<!--else-->
HTML code that is only displayed if the expression is not true.
<!--endcondition-->In the configuration file: _variable=dat_field=date()
<!--_variable-->
HTML code that is only displayed if the date field "dat_field" equals today's date. The expression is contained in the variable _variable in the application configuration file.
<!--endcondition-->
A set number of records may be displayed in a template using the <!--repeat-->, <!--endrepeat--> directives. The number of records displayed is determined by the _display variable in the configuration file. The number of records displayed may be changed by sending a _display variable to baserunner that overrides the _display variable in the application configuration file. The new _display variable must be sent with a display action. Normally this will be accomplished with a form:
| <form
action="/cgi-bin/baserun.exe?_ses={session}&_act=display&_tar=template.htm"
method="GET"> <p><input type="text" size="3" name="_display" value="{setdisplay}"> <input type="submit" value=" Show "></p> </form> |
Within a repeat block, you may use the <!--alternate--> directive. Using this directive will display the the code preceding <!--alternate--> for the one record and the code following <!--alternate--> for the next record.
Navigation actions when multiple records are displayed will skip the number of records displayed (forward or backwards).
<table>
<tr>
<th>Record Number</th>
<th>Heading</th>
<th>Heading</th>
<th>Num Heading</th>
</tr>
<!--repeat-->
<tr>
<td>
<a
href="/cgi-bin/baserun.exe?_ses={session}&_tar=target.htm&_act={ltrim(str(recno()))}"
Details</a>
<td>{trim(chr_field)}</td>
<td>{dtoc(dat_field)}</td>
<td>{str(num_field, 10, 2)}</td>
</tr>
<!--endrepeat-->
</table>
This example uses a table to display X records from the database, X being the value baserunner finds for the the _display variable. This example also adds a link within the table to a single record template, using the record number as its action. Navigation actions for a multiple record display are identical to those for a single record display, except that they move the record pointer X records, forward or backwards.
<table>
<tr>
<th>Heading</th>
<th>Heading</th>
<th>Num Heading</th>
</tr>
<!--repeat-->
<tr>
<td>{trim(chr_field)}</td>
<td>{dtoc(date_field)}</td>
<td>{str(num_field, 10, 2)}</td>
</tr>
<!--alternate-->
<tr>
<td bgcolor="XXXXXX">{trim(chr_field)}</td>
<td bgcolor="XXXXXX">{dtoc(date_field)}</td>
<td bgcolor="XXXXXX">{str(num_field, 10, 2)}</td>
</tr>
<!--endrepeat-->
</table>This example uses an <!--alternate--> directive to change the background color of every other row in the table.
Lists display data for each record in the current record set. Each list must have a unique name, containing the string "list." Lists are created using the directives <!--listX--> and <!--endlist-->. You may use whatever naming convention you wish: something like <!--list1-->, <!--list2--> <!--list3-->, etc. is probably the simplest. The <!--endlist--> directive does not change. All the code between those directives is repeated for each matching record. The list is cached in the session database, so it is only generated when the filter changes. Lists may not contain other lists.
A list may be sorted. To sort a list, provide a variable in the configuration file with the same name as the list prepended with a "_", e.g., _list1. The value of the variable should be the expression used to set the sort order: e.g. "field_name" or a more complex ordering, alltrim(last_name)+alltrim(first_name). If you wish to have multiple sort orders available for the list, you can also pass the variable through a form or the command line. The sort ordering for a list (or a unique list) has no effect on the sort order for the database. Note that an expression used to sort a list must not return a logical value.
When dealing with large databases, you need to take care when generating lists. A list of thousands of records could take a very long time to generate and send to the user. Most often, you should use lists only when a filter is in effect.
Lists, along with unique lists, are processed in a different way from normal single or multiple record displays. Lists do not use the current record position and they do not affect the current record pointer. All lists start from the first record, either in the database or in the current filtered set of records, and process each one to the last record. For instance if you set the _display variable to a very big number (more than the number of records in the database, say), and generated a table using the <!--repeat--> directive, it would look the same as a list generated from the same data. But the processing that baserunner does to generate those is quite different. Using <!--repeat-->, the record pointer would be moved to the last record displayed, using a list, the record pointer would not be affected.
Lists, unique lists, and totals also differ from normal record display in that baserunner may cache the results of those blocks to avoid having to regenerate the list the next time it is used. Once a list is cached, it will be inserted from the session database where it is held. The list will only be regenerated when a new filter is put in effect. In the example application, for instance, the list that is used to look up records in the single record template, is only created when a new filter is placed on the database. This caching greatly improves performance for lists that are used on multiple pages.
Now, there are situation where the caching mechanism is not appropriate. If, for instance, your main display in an application consists of a list (or a unique list), the caching mechanism could actually slow down your application. Under such circumstances, you can use the _nocache variable. This will eliminate all of baserunner's internal caching.
<table>
<tr>
<th>Heading</th>
<th>Heading</th>
<th>Num Heading</th>
</tr>
<!--list1-->
<tr>
<td>{trim(chr_field)}</td>
<td>{dtoc(date_field)}</td>
<td>{str(num_field, 10, 2)}</td>
</tr>
<!--endlist-->
</table>
This list displays the contents of chr_field, date_field (formatted according to the value of the _dateformat variable), and num_field (formatted to show a maximum of 10 digits and 2 decimal places) for each of the records in the database that are currently selected in an HTML table. If you were to include a _list1 variable in the configuration file, the list would be sorted on the expression the was included there.
<form action="cgi-bin/baserun.exe" method="GET">
<input type="hidden" name="_ses" value="{session}">
<input type="hidden" name="_tar" value="record.htm">
<select name="_act" size="1">
<!--list2-->
<option value="{ltrim(str(recno()))}">{trim(chr_field)}
</option>
<!--endlist-->
</select>
<input type="submit" value=" Look up ">
</form>This form uses a list to populate a select list that can be used to look up a particular record. In this form the value is set to the record number which is passed to baserunner as the _act variable. Selecting a record from the list will position the record pointer to the selected record number and display that record using the template "record.htm." If a _list2 variable is supplied, the list would be sorted on that expression.
Unique lists, like normal lists display data for each record in the current record set; however only unique values are displayed. Each unique list must have a unique name containing the string "unique." Unique lists are created using the directives <!--uniqueX--> and <!--endunique-->. You may use whatever naming convention you wish: something like <!--unique1-->, <!--unique2--> <!--unique3-->, etc. is probably the simplest. The <!--endunique--> directive does not change. The unique list is cached in the session database, so it is only generated when the filter changes.
Each unique list must be associated with a variable in the configuration file that has the same name as the unique list, prepended with a "_", e.g. _unique1. The value of this variable must contain an expression that will be evaluated to determine whether the record contains a unique value: e.g. "field_name" or a more complex ordering, alltrim(last_name)+alltrim(first_name). You may also pass this variable through a form or on the command line to change the unique list within an application. Like all expressions used to sort data, this expression may return any type except logical.
All the code between those directives is repeated for each matching record, but only one instance of each unique value will be displayed. The unique list is cached in the session database, so it is only generated when the filter changes.
| <UL> <!--unique1--> <LI>{trim(chr_field)} <!--endunique--> </UL>
<!--Filter-->
|
The first example presents each unique value in the field chr_field in an unordered list. The unique list is sorted on chr_field. The second example uses a unique list as a menu for a refine action. In this case the list is only shown when a filter is in effect.
Inserting a total block into a template will display the total of any expression contained in tags within the total block. Total blocks are created using the directives <!--totalX--> and <!--endtotal-->. You may use whatever naming convention you wish: something like <!--total1-->, <!--total2--> <!--total3-->, etc. is probably the simplest. The <!--endtotal--> directive does not change. The expressions will normally return a numeric type, but returning a character type that consists of numbers is acceptable, and, in some cases, especially when using expressions that do calculations, it is more reliable to create an expression using the str() function, e.g., {str(num_field/60,10,2))}. Expressions that cannot be evaluated as numbers will be ignored. A total block is cached in the session database, so it is only generated when the filter changes.
The directives <!--averageX--> and <!--endaverage--> work identically to <!--totalX-->, but the average values of the expressions contained in the block are displayed.
By default, two (2) decimal places are shown for the results of expressions contained in total or average blocks. You may set the number of decimal places to display by inserting the number, enclosed within parentheses "( )" into the name of the block, e.g. to show no decimal places: <!--averageX(0)-->; to show three decimal places: <!--total1(3)-->.
<table>
<tr>
<th>Heading</th>
<th>Heading</th>
<th>Num Heading</th>
</tr>
<!--list1-->
<tr>
<td>{trim(chr_field)}</td>
<td>{dtoc(date_field)}</td>
<td>{str(num_field, 10, 2)}</td>
</tr>
<!--endlist-->
<!--total1-->
<tr>
<td>Total:</td>
<td> </td>
<td>{str(num_field*1.4),10,2))}</td>
</tr>
<!--endtotal-->
<!--average1-->
<tr>
<td>Average:</td>
<td> </td>
<td>{num_field}</td>
</tr>
<!--endaverage-->
</table>
This example uses the same list as the example above, but adds a row to the HTML table that gives the sum of the num_field field.
In some cases, baserunner (and HTML) may have difficulty displaying the extended characters used by many European languages. If this proves to be a problem in your application, you may add the logical variable _translatehtml to your configuration file. If that variable is present, baserunner will replace these character entities with the corresponding HTML character code. This works on all ASCII characters with numeric values above 126.
|