This document is the first section of the SurferScript Reference, describing the template HTML extensions used to customize the ScreenSurfer Web Gateway.
There are a number of samples distributed in the ScreenSurfer directory \screensurfer\hostserver\Templates. The Harvard.stml demonstrates a number of the macros and techniques available for enhancing a site.
Be sure to complete or at least browse the ScreenSurfer Tutorial. Each Tutorial section starts with a useful key skills directory with links to the section describing each skill.
The parser for the template files is relaxed regarding the case used for tags, macros and expressions, much like browsers are relaxed regarding the case of HTML tags.
This means that, as in a number of examples, you can use any case (all lower, all upper or any mix) when defining template tags as well as embedded expression functions.
SurferScript utilizes the concept of In-stream programming, an optimal approach to user-interfaces that are based on HTML. Since so much of HTML formatting is based on literal text, SurferScript makes HTML the "primary" language, and models its logic and functions within the HTML paradigm. This is different than creating HTML user interfaces in languages such as BASIC or C, since in these languages all "output" is displayed using functions or macros. With SurferScript, all text that occurs in the program that isn't a comment or a special SurferScript tag is sent to the browser as it is encountered as a stream.
Other tools have pioneered this approach, namely Cold Fusion from Allaire. The ScreenSurfer authors simply recognized in-stream programming as the most productive approach to HTML user interfaces and built upon the concept. Since delivery of HTML user interfaces in an emulation environment is so dynamic, SurferScript files are not built around single HTML files, but around the concept of modular sections of HTML and commands contained in one or more STML files.
In a typical web server environment, the events-to-script/html is a simple model; an HTTP "hit" is received (from a user keying-in a URL at a browser or clicking on a link) and the web server opens the corresponding file, and starting at the top displays/interprets that file.
With ScreenSurfer, the types of events are far more complex and granular making a one-to-one correspondence between events and files somewhat unwieldy. To address the modular requirements of mapping events to HTML and script, the <TESECTION> tag is used to not only identify an event (to attach the enclosed HTML and script to) but also to organize events and scripts within modules.
Any given page delivered by a ScreenSurfer application may be produced by a single section or many sections combined by the developer (and by events) into a single HTML page. Any section of SurferScript can include another section from the same STML file or a different file (using the TEPUTSECTION or TECALL tag).
Typical Layout of a SurferScript Template file (.STML file) | |||
---|---|---|---|
| |||
|
To review, SurferScript is organized into sections containing HTML and HTML Extensions, all contained in standard ASCII files with an extension of .STML. Each section of SurferScript begins with the TESECTION tag, which is described in more detail following this introduction.
<TECONNECTED WHEN Screen_row_column {IS | ISNOT} "TEXT" [AND Screen_row_column] [...]>
You typically code one or these per connection (host). The TECONNECTED tag provides
ScreenSurfer with help in identifying a successful host connection.
It is important to define both top and bottom text areas of a screen in
a TECONNECTED tag, as many screens are created by the host using multiple
writes. The TECONNECTED tag is a simple, standalone tag. To enhance or identify the initial screen, you also need a TESECTION tag (following).
Executes/sends the specified section. Typically used for SurferScript that is re-usable across more than one screen or transaction. Note that a multi-part name is supported; sections local to the current template file can be specified alone. When specifying a section in a different template file, you need to include the template name (without any file extension) followed by a period and the target section.
For more information on the use of parameters with TECALL see the Procedural TESection description.
TEPUTSECTION Examples | |||
---|---|---|---|
| |||
|
This tag is particularly useful when the <TEIF> tag is used, which requires a CRLF on the same line, or a number of <TERECIPIENT> tags inside a <TEMAIL> block. When inside the <TENOTEXT> tag, all output created by SurferScript tags (including the <TESHOW>) is still output to the HTML page, so when "things get complex" inside a <PRE> or <TEMAIL> tag, surround with a <TENOTEXT> / </TENOTEXT> block and perform all HTML output with <TESHOW> expressions. Note that when you do need to include a carriage return that the "\n" sequence (backslash, 'n') can be included in your <TESHOW> output string to send a CRLF to the output stream.
Note that the optional attribute BREAKS can be used to suppress only carriage returns (line breaks)-- this can provide a comprimise between suppressing all text and supressing just the annoying line breaks that follow each SurferScript tag...
TENOTEXT Example | |||
---|---|---|---|
| |||
|
Note that all TESECTION tags share the following characteristics:
<TESECTION Name> [<TEDECLARE PARAMETER Name Type Length [Use="IN|out|inout"] [Data="text"]>Any time you need SurferScript that you would like to use in more than one case, put it into its own section without any event definitions in the TESECTION tag. All SurferScript between the plain TESECTION tag and the ending </TESECTION> (or the next TESECTION) will be executed when called with the TEPUTSECTION tag.
New in version 3 of ScreenSurfer (and later releases of 2.0) is the TEDeclare Parameter, which introduces the ability to pass parameters when calling the procedural TESECTION.
Since the addition of parameters to TESECTION blocks provides a far more modular programming environment, the TECALL tag was introduced as a substitute for the TEPUTSECTION. TEPUTSECTION was originally named when SurferScript was primarily a means of streaming-out HTML (thus the "put" in the tag name). You don't "put" a procedure or function; you "call" it, so we added the TECALL as a more natural tag to use when executing procedural TESECTION script blocks.
When you declare parameters, they will work inside the TESECTION only and will work just like a TEDECLARE VAR (see TEDECLARE VAR for a description of the parameters of TEDECLARE PARAMETER).
One extension past the simple TEDECLARE VAR is the Use="IN|out|inout" attribute, which defines how a parameter is used. The out and inout types actually return data to the calling script, and because of this the expression matching an "out" or "inout" parameter type must be a single variable name. This is a logical restriction of the OUT and INOUT parameter types so that there is a sensible "target" for the returned data.
The order in which the parameters are declared (yes, you can have one or more parameters) determines the order in which they are specified in the TECALL tag). As with many SurferScript tags, the TECALL can simply include expressions separated by "whitespace" (blanks, tabs or carriage returns) but if this technique is used, all of the parameters must be included in the TECALL.
A powerful capability of the SurferScript parameters is the optional parameter which is made possible when the data="text" attribute is included in the TEDECLARE PARAMETER. When the data attribute is included, the parameter may be omitted in the TECALL tag, and at the start of the called TESECTION the parameter will be initialized with the text specified in the data attribute. Note that in order to utilize the optional parameter feature, the TECALL tag must utilize the name=value (named parameter) form.
Note that as with all TESECTION tags, any TEDECLARE VAR tag which defines a variable and is contained within a specific TESECTION, has a name associated with that section when addressed anywhere else in your template files. By defining variables inside a section (when they are associated with that section!), you give an object-oriented identity to that variable and improve the readability of your code.
TESECTION Example | |||
---|---|---|---|
| |||
|
TESECTION Output Parameters Example | |||
---|---|---|---|
| |||
|
Event | Declared With / Description |
---|---|
Host Screen Display |
TESECTION Name WHEN Screen_row_column IS "Text" --OR-- TESECTION Name WHEN Screen IS EMPTY (for blank, unformatted screens) Use this to identify a screen you wish to customize-- all screens that are not identified in this type of TESECTION are displayed using the global.default section. When a screen that matches the criteria is displayed, the SurferScript in this section will be executed. |
Update to current screen |
TEEVENT HOSTEVENTNAME
WHEN Screen_row_column IS "Text" Used to catch errors on the current screen. For example, whenever line 23 is non-blank, it means there is an error. Must be positioned prior to the </TESECTION for the screen section it applies to. |
URL from Browser (like a CGI request) |
TESECTION Name WHEN TRANPATH_part IS "Text" Use this to identify a URL you wish to act upon. A URL can have multiple parts separated with forward slashes, just as with a file directory path. These types of URL's in ScreenSurfer are called transaction URLs and have no file extension. Use a transaction URL anytime you want SurferScript to be triggered from the browser using a link or button! |
HTML Form Submit (From last page displayed) |
TEEVENT WEBINPUT
If you customize a screen using a TESECTION, you can have SurferScript execute before the user's input is sent to the host. To "hook-in" to this event, you specify the TEEVENT WEBINPUT tag before the /TESECTION tag. All SurferScript between the TEEVENT WEBINPUT and the /TESECTION will execute when the user submits the form created in the current TESECTION. |
Function Key Pressed |
TESECTION Name WHEN AIDKEY IS "mnemonic" (example: "[pf1]") In many application environments, certain function key requests can have significant global impact on the screens that will follow. You can capture these requests and manage them appropriately using this type of TESECTION. If you don't capture a function key, it is processed normally by ScreenSurfer as a standard emulation function. |
Interval Timer Elapsed |
TESECTION Name WHEN TimeInterval IS Seconds This is one of the special "background" events new in ScreenSurfer 1.3E. These are driven by time and create HTML pages in the \screensurfer\hostserver\events directory. The TimeInterval setting will create a thread which will execute the defined section every N seconds. |
Date and Time |
TESECTION Name WHEN DATETIME IS YYYY-MM-DD-HH-MM-SS Section will be executed whenever the DATETIME expression is true. |
Day of the Week and Time |
TESECTION Name WHEN DAYANDTIME IS DayName-HH-MM-SS Section will be executed whenever the DAYANDTIME expression is true, using english names of the week (Sunday, Monday, Tuesday...). |
Execution Error (Exception) |
TEEVENT CATCH
If this is defined prior to the </TESECTION> and an execution error occurs, the SurferScript between this tag and the </TESECTION> will be executed. Examples of errors include bad database SELECT or timeout on Connection. |
<TESECTION [SECURE] ScreenName> [WHEN SCREEN_row_column {IS|ISNOT|=|<>} "text" [AND | OR...][...]] [WHEN SCREEN IS EMPTY] [PATHTO ScreenName IS Keystring]>The Screen-driven section is the primary device for matching HTML templates to existing screens, without the need to "keep track" of which screen is currently displayed. For a pictorial example of a typical Screen Section, see the ScreenSurfer Guide: SurferScript Example.
All screens not defined in this type of section will flow through the global.default section, so you use this tag to identify a specific screen, then follow with the HTML you want for that screen.
This tag usually will use one or more Screen_row_column IS "text" clauses to identify static text (that is consistent) on the target screen. The DevCenter includes a component which is part of most of its wizards which make the generation of this tag easy, using point and click definitions.
The WHEN SCREEN IS EMPTY clause is a special case specifically for identifying an unformatted, blank screen. This avoids the need to define 24 tests, each for a blank line of 80 characters! It is mutually exclusive with the use of the WHEN SCREEN_row_column format.
TESECTION Screen Example | |||
---|---|---|---|
| |||
|
Example of BOOLEAN Combinations in TESECTION | |||
---|---|---|---|
| |||
|
The Screen Navigation Rule-Base is populated as all template
files are compiled using each section's "PATHTO" clause. For
example, the "MAIN_MENU" screen displays any number of screens, each
which returns to the main menu with the F3 key; if the screen ORDER_MAIN
has the following, than ScreenSurfer will be able to handle the
Web Browser "back button" to go from ORDER_MAIN to the MAIN_MENU without
any errors:
PATHTO Example | |||
---|---|---|---|
| |||
|
ScreenSurfer performs the re-routing of the user using a basic level of JavaScript. For non JavaScript capable browsers, switching between the SECURE mode and non-secure mode is not automatically managable by ScreenSurfer (you can do this yourself by providing the user custom links to "enter secure mode" and "exit secure mode", or simply use a default secure mode by having the user access ScreenSurfer completely through the SSL port (see following).
The next screen to be displayed which does NOT have the SECURE attribute, will cause ScreenSurfer to re-route the user through the standard ScreenSurfer port. How ScreenSurfer works with the SECURE attribute is controlled with the registry entry HKEY_LOCAL_MACHINE/Software/iE/ScreenSurfer/Config/SecurityDefault. Whenever this setting is a "0", ScreenSurfer will switch the user between a secure port and the standard port. If this setting is "1", ScreenSurfer will ignore the user's status (whether or not in a Secure Port). If you want all user communications to run through the SSL port, then simply set the SecurityDefault setting to 1, and have users access ScreenSurfer starting with the HTTPS port of your IIS machine.
Secure Logon Screen Example | |||
---|---|---|---|
| |||
|
<TESECTION SectionName> [WHEN TranPath_n IS "TEXT" [AND...]]>To execute SurferScript based on an HTTP event, such as a user clicking on a link or submitting a form, you use the TESECTION with a "Tranpath" set of criteria.
This works just like traditional CGI calls where you identify a particular URL to be mapped to some code. Web servers typically use a unique file extension to identify a CGI call; with ScreenSurfer, it is any URL which has no file extension and is not one of the "built-in" URL commands such as /surfer/emulator, /surfer/refresh and /surfer/exit.
You map a submitted URL to a transaction TESECTION using the TRANPATH_n descriptor, where the n identifies the part of the URL starting with the first value after the /surfer/ and with forward slashes separating the transaction path parts.
The Transaction Recognition Rule-Base is populated as all template
files are compiled using each transaction section's "WHEN TranPath..." clause.
Note that the compiler is very touchy about ambiguity, and will reject
any transaction definitions that have insufficient detail to enable runtime
differentiation. You cannot mix both transaction and Screen_ WHEN
clauses, as a Transaction section is not necessarily connected to
a single screen. You can recognize virtually any URL targeted to
ScreenSurfer using up to 4 parts in the transaction name.
Transaction Section Example | |||
---|---|---|---|
| |||
|
<TESECTION Name> [WHEN AidKey IS "mnemonic"]>This section will be executed whenever the user selects the identified AID key either by clicking on a button or one of the provide keyboard GIFs. An AID key is any key which causes the screen to be submitted to the host, such as the [enter], [pf1]..[pf24] and so on. See the Keystroke mnemonics table for a list of valid mnemonics.
There are very special cases when you would define this kind of section. The most common would be to capture the PF1 Key as part of implementing a Help System.
Note that this event will only occur when the standard /SURFER/EMULATOR URL is active, which is the default URL for a TEFORM tag. Since this is the standard method of delivering ScreenSurfer screen pages, you can count on the AID section capturing the AID key when you need it to.
NOTE: When you specify an AIDKEY section, the AIDKEY section replaces standard AID key entry.
AidKey Event Example | |||
---|---|---|---|
| |||
|
<TESECTION Name> [WHEN TimeInterval IS Seconds] OR [WHEN DateTime IS YYYY-MM-DD-HH-MM-SS] OR [WHEN DayAndTime IS DayOfWeek-HH-MM-SS]>Time-based events provide ScreenSurfer application developers with a background task capability to enable a variety of functions. For example, each minute, all timed-out sessions can be "swept". Each morning at 6am, a script can query a number of host applications and send an e-mail with the results.
All of the time-driven events will write an HTML file to disk in the directory \screensurfer\hostserver\events with the name of the file based on the name of the section which generated it. The contents of the HTML file are whatever is generated inside the section.
Examples of DateTime Specifications
Sample | Description |
---|---|
*-1-1-6-0-0 | Any year, January 1 at 6am |
*-*-1-16-0-0 | Any year, Any month, on the 1st at 4pm |
*-*-*-23-0-0 | Any year, Any month, any day at 11pm (every day at 11pm) |
*-*-*-*-10-0 | Any year, Any month, any day, any hour, at ten after (once an hour) |
*-*-*-*-*-0 | Once a minute! |
*-*-*-*-*-* | Better have a fast machine |
Examples of DayAndTime Specifications
Sample | Description |
---|---|
Monday-6-0-0 | Every Monday at 6am |
Friday-19-0-0 | Every Friday at 7pm |
Time-driven Section Example | |||
---|---|---|---|
| |||
|
<TEEVENT WebInput> --OR-- <TEEVENT HostEventName WHEN SCREEN_row_column$ {IS|ISNOT|=|<>} "text" [AND...][...] --OR-- <TEEVENT Catch>
The TEEVENT tag gives the template author the opportunity to execute template code at different points-in-time related to the processing of a host screen section. The TEEVENT tag must be placed after the <TESECTION> and before the </TESECTION> (or the next <TESECTION>.
You may have more than one <TEEVENT hosteventname> tag in a given section, but only one <TEEVENT WEBINPUT> tag and only one <TEEVENT CATCH> tag is supported per section.
When you place a <TEEVENT WebInput> tag in a section, any template code existing between it and the next <TEEVENT>, </TESECTION> or <TESECTION> tag will be executed in-between the entry of user web data to the active host screen and the processing of any related AID key. This enables your template code to read and process web variables (variable names starting with "web." can read HTML data values) as well as read/manipulate user entries to the host screen.
When you place a <TEEVENT HostEventName> tag in a section, any template code existing between it and the next <TEEVENT>, </TESECTION> or <TESECTION> tag will be executed whenever a screen update by the host from the current section matches the WHEN clause in the TEEVENT tag. The HostEventName you use is arbitrary, and is generally only relevant for error and status reporting purposes.
When you place a <TEEVENT Catch> tag in a section, any errors that occur during the execution of your SurferScript will cause execution to jump to the SurferScript following this tag. Note that if you perform a <TESET Task.ErrorComponent=""> in this section, that you will prevent ScreenSurfer from displaying the ERROR component table, which has information to the user about the current error, but may be confusing in a live environment. Generally, the <TEEVENT CATCH> tag is very useful for situations where you know that an error will occasionally occur, such as in a section with a lot of SQL. Sometimes you would rather not have detailed error handling for the 99.9% of the time that no errors will occur...but would like a place for execution to jump to should an error occur.
Global.HOME | Used for the "home page" and any unrecognized URL if a user enters the address of the ScreenSurfer server in their browser, the SurferScript in this section will be executed and resulting HTML sent to the user's browser. If you are implementing a frames environment, you will probably put the top frameset definition in this section. | ||||||||
Global.default |
Used for all screens not declared in a Screen TESECTION. This is the section that all "default emulation" screens are passed-through.
You can modify this section all you want in order to customize the default pass-through screens of ScreenSurfer, although you should maintain the sequence of the following tags, as they are key to the provision of a reliable emulation session:
| ||||||||
Global.INVALID | Used for invalid or timed-out HTTP requests where the user submits a page and no longer owns the session. | ||||||||
Global.NO_SESSIONS | Executed when a user has requested a CONNECT for a specific group and there are no sessions available | ||||||||
Global.TIMEOUT | Executed when a session times-out. Note that this is a "background" execution, which will create a file \screensurfer\hostserver\events directory\Timeout_n where n is the sessionId of the user's session. If not specified, the timed-out session is stopped completely and restarted for a new user. By including this section, you can prevent the "stop" and "restart" and position the screen to a new user logon instead. | ||||||||
Global.ScreenTimeOut |
Executed when a transition times-out. This is at the same point that an Event Log entry is written which says "Screen Transition: Http Thread". This can occur in a TEACTION ENTER or when a user is executing pass-through emulation. The TimeOut value is set using the Screen.TimeOut variable, which is defaulted to 20 seconds.
This section will be displayed to the user at the browser, or you can suppress output by the user by utilizing the TEMAIL and the Profile="DiskFile" attribute in TEMAIL to create a "dump" of the current screen and other user information. If you use the Now() function to name the file, along with Screen.SessionID, you can have a unique file for each timeout, named by session... | ||||||||
Global.StartUp |
Executed immediately after a compile, before the HTTP port for requests is opened. This will occur at ScreenSurfer service start, or when a compile is requested from the DevCenter.
This section is useful for initializing global values that are stored in a database, so that the initialization occurs once. For example, a "Server." variable can be set in this section to create combo boxes or other HTML text. | ||||||||
Global.ShutDown | Executed after the HTTP port has been closed and ScreenSurfer is about to clear active sessions. This occurs immediately before a compile or when the ScreenSurfer service is shutdown. | ||||||||
Global.ScriptError |
This section will execute in place of the standard script error display, which is a table including the error component and text description of the error. An example follows which essentially reproduces what the standard script error displays. Note that if you implement this section you need to check on the availability of a session using the Task.SessionActive variable prior to including any Screen. variables if you want these to display correctly to the user.
Logging to a disk file can be very effective in tracking errors; note that all script errors are also logged to the event log.
|