| Software Development Documentation | Development Overview | WCTL Template Language | WCTL Commands | WCJS Server-side JavaScript | WCMS Development | Chat Development | Standard Templates & URL Codes | Operator Documentation |
Visit the
Using the Web Crossing Template Language
Web Crossing supports both its own template language (WCTL) and built-in server-side JavaScript. You can use whichever language you prefer to customize your site. WCTL is extremely fast but is not as convenient or as extensible as the server-side JavaScript. However, you can call JavaScript from WCTL, and you can call WCTL from JavaScript, so you can mix these two scripting languages as appropriate.
WCTL directives are identified by two percent signs, the command, and then two more percent signs, i.e. %%...%%. If you enter
Hello <b>%% username %%!</b>
the actual display seen by the user will be something like
You can use // and # as comment delimiters through the end of the WCTL expression. For example:
A template is the HTML text for an entire page or portion of a page to be served by Web Crossing. You can enter templates in the various sysop control panels to easily customize much of the apperance of your site, such as the banner and footer for each page.
In addition to the sysop control panel, you can use the webx.tpl file to customize your entire site. The webx.tpl file is a collection of templates and macros to be used by Web Crossing. You can specify template macros for any of the user interface pages served by Web Crossing. You can also define your own templates to create your own unique pages, or define your own templates as a convenience when the same HTML and WCTL directives are used in more than one place. An optional template file, webxsetup.tpl may be used. If this file is present, it is included before the webx.tpl file. This file is intended for language setup and other functions that need to be defined regardless of any errors in the main webx.tpl file. You can also use a special include file syntax to organize your template code into separate files.
Web Crossing also reserves several template files for internal use:
webxextn.tpl, webxcalendar.tpl, webxmail.tpl,
and webxtour.tpl.
These files are used by Web Crossing, Inc. to deliver drop-in updates to Web
Crossing, and should never be modified, deleted, or renamed. Features enabled by
these files may be disabled with the "Other Settings" form on
the sysop Control Panel. A template defined in
one of these files may be overridden by defining a template of the same name in
your webx.tpl. If you have already defined a template in
webx.tpl and later install an updated Web Crossing file which
also defines that template, the original template will continue to be
used by Web Crossing.
If there is no whole-page template, then Web Crossing will construct
the page from smaller pieces.
These pieces are specified through the sysop control panel
or through templates in your webx.tpl and webxextn.tpl files.
The template files are checked first, and if a template
is defined therein it is used; otherwise, the sysop control panel setting is used.
When Web Crossing builds a response page, it starts with the sysop-defined banner,
adds items appropriate for the response, and concludes with the
sysop-defined footer.
You can do extensive customization of each page through the various sysop
control panels. You can edit default HTML text, and
you can use WCTL directives as appropriate.
Building response pages
When Web Crossing builds a reponse page,
it firsts checks the webx.tpl and webxextn.tpl files to see
if a whole-page template macro has been defined for the response.
If so, this template macro is used to build the entire page.
For example, you can replace the entire login page by
specifying a %% macro login %% in your webx.tpl file.
Where to go from here
You can customize many aspects of Web Crossing through the sysop control panel.
To customize whole pages, follow the
step-by-step instructions for variables and templates,
and some examples of putting all this together.
The steps to customize whole pages are as follows.
%% macro login %% ...contents of login template... %% endmacro %%
All of the templates used to layout a folder page are optional. They may be specified through the sysop control panel, through the webx.tpl file, or on a folder-by-folder or discussion-by-discussion basis.
You can optimize the environment when there are very large numbers of discussions in each folder by attaching a btree to each folder. The btree commands include pathAddBtree, pathRemoveBtree, pathHasBtree, pathBtreeSpec, and pathBtreeKey
The btree is sorted by date, and pathSelect has some additional options to select a btree range. Instead of having to interate thousands of entries in the directory, you can now just look at the ones in the "recent" date-range.
For more detail on the folder templates, see the Folder template sections.
All of the templates used to layout a discussion page are optional. They may be specified through the sysop control panel, through the webx.tpl file, or on a folder-by-folder or discussion-by-discussion basis. (If specified in a folder, then all discussions in that folder will share the same templates.)
For more detail on discussion templates, see the Discussion template sections.
To continue this example, you can allow users to edit their phone number in their user-preferences form, by adding the following to the editPreferences template:
Your phone number: <input name=user.phone type=text size=30 max=50 value="%% user.phone %%">
Note that %% user.phone %% will show the current phone number for editing.
To display a user's phone number in your site's personal information form, use author.phone in the userInfo template, such as
%% if author.phone %% Phone number: %% author.phone %%<p> %% endif %%
This will display the phone number if available.
WCTL expressions are not case-sensitive, so "username" is the same as
"USERNAME" or "UserName." You may place blanks inside the %% marks for readability.
For example,
You may use tabs to indent conditional sections.
All of these leading tabs are automatically removed from the output.
In order to make it WCTL easier to read, the newline
following a directive is also removed. For example,
All variables evaluate to either a text string, an integer number, or to a
boolean (true/false) value.
For example, %% username %% evaluates to the name of the current user,
while %% if userIsSysop %% takes the true branch if the current user is the sysop.
Text variables may evaluate to an empty string, that is, a string with no characters.
For example,
%% user2ndLine %%, the second line of user information,
will be empty until a user fills it in.
In an if test, text strings are true when they have any characters,
and false when they are empty. For example,
will only insert <p>Other information:... when there is a second line.
Numeric values are considered to be true if they are non-zero, or false if they are zero.
String and integer values are automatically converted as required.
A non-numeric string is converted to the integer value 0.
For example,
Boolean variables are 0 for false and 1 for true.
You can use boolean variables to control the text that is placed into the
page returned to the user.
For example,
Operator precedence, from highest to lowest (highest are done first):
Numeric constants can be a number, such as -5, 0, or 1429.
They can also be the integer value of a character, such as 'a' or 'Z'.
String constants are in double-quotes, such as "abc."
The empty string is "".
To put a double-quote character in a string, repeat it, such as
"""" (which evaluates to a string of one double quote).
For example,
When a user first connects to Web Crossing, they
are given a unique session ID that is dynamically inserted into all of the links into
Web Crossing on each page that is served. Session variables are tied to this session ID,
so you can keep easily keep track of state across multiple requests.
For example,
In the user registration and editPreferences templates, you can use these
variables as the name of an input field, and Web Crossing
will automatically set them for you when it processes the form.
For example, adding
For example, in a message display or personal information form,
For example,
Sometimes you want to find a value from either the current location or,
if not defined there, then from the
closest parent that defines it. This allows you to use "inheritance"
by folder and discussion hierarchy.
To find the closest definition of a value, use path$varname.
For example,
For example,
The built-in location and pathXxx variables a reference the current
location in the Web Crossing forums. You can change the current location
with setPath(...).
Values for custom "path" variables like path.customFooter
must be assigned to each folder/discussion/message object. They do not inherit
values from the same variables in their containing objects, but you can use
path$customFooter to reference either the value from the current location,
or from the closest parent if not defined in the current location.
will display as
The conditional commands are if, else, endif, else if,
elsif, and elseif. (The various "else if" options are all equivalent.)
You can use any built-in variable or expression in an if test.
Empty strings evaluate as false, and non-empty strings as true.
You can also use
Guest session values are preserved when the user logs in or registers.
In a while loop, you can use %% break %% to exit the loop, and
%% continue %% to go to the top of the loop.
For example, the following rather contrived loop will display all the
even numbers less than 100:
In order to prevent infinite loops, Web Crossing limits the maxiumum number of
while-loop iterations per page. The default setting is 1000, and can be changed
through the sysop General Settings panel.
is a macro that evaluates to something like Hello World on Feb 26, 1998.
The webx.tpl file allows you to define macros for a variety of uses.
When Web Crossing constructs a reponse to a URL, it first
checks the webx.tpl and webxextn.tpl files for a
template macro for the response.
The template macro for a specific request is located by name;
see the Standard Templates
document for a listing.
The standard.tpl file contains a complete set of
default templates that you can easily customize for your site.
Before Web Crossing gets a value from the sysop control panel,
it checks to see if this value is defined in the webx.tpl
or webxextn.tpl files. (This allows you to define all of the
sysop settings together in webx.tpl.)
Again, see the Standard Templates
document for a listing.
Note: after you make changes to the webx.tpl file, you must
click on the "Reset file cache for HTML files and webx.tpl
templates" link
in the sysop control panel, in order for Web Crossing to pick up your changes.
The template you call can be either built-in or one you have defined.
There is a maximum depth of 50 calls, so that infinite loops (e.g.
a calls b, b calls a) don't run forever. Nested macros may be called
using macro1.macro2... syntax. For example, % % use level1.level2.level3 // calls the nested level3 macro % % When nested macros are used the logic checks for the called macro up the containment tree first, then
checks the customization macro for the current location. For example, % % macro nested // 1 % %
case 1
% % use nested // calls 2% % % % macro nested // 2 % %
case 2
% % use nested // calls 2% %
% % endmacro % %
% % endmacro % %
% % endmacro % % % % macro nested // 3 % %
case external
% % endmacro % %
The functions are
To define your own pages, use the following steps:
It is good practice to put an underscore in your template name, because Web Crossing built-in
templates will never use this character.
If you need a user to be logged in before a full-page template macro should be used, you can
insert the following check at the start of the macro:
When a full-page template macro returns all white space, Web Crossing
will display a login page. On a successful login, the original template macro
will be reexecuted with the same parameters.
You process a form by linking the submit button to a Web Crossing template.
For example,
where myFormProcess is the name of your form-processing template.
Web Crossing will replace
%% urlBase %% with the base URL for your Web Crossing server,
%% certificate %% with the user's current access certificate, and
%% location %% with the user's current location in the Web Crossing conference.
(These are all standard components of a Web Crossing URL.)
If you are running with FastCGI, all of the environment
variables are avaiable. Through the standard CGI, you can only access a subset of the variables.
To get a list of variables in your environment,
use the showEnvir template from standard.tpl.
You first need to move the showEnvir template into your webx.tpl file,
as described in the
Customizing Whole Pages section.
Then use a URL to access Web Crossing as
If you need to know whether a request came in over a secure SSL connection or not,
use envir.url_scheme. In direct web-service mode, this will be "https" for
a secure connection, or "http" for a non-secure connection. For FastCGI mode, this
will be set per the originating server, so may be missing or null;
instead of url_scheme, Apache servers
set https if the request was over an SSL connection.
In CGI mode, no information is available. (You can also check envir.https,
which is set to "on" whenever url_scheme is "https".)
To send a cookie along with the response to the client,
use something like
To get the value of a cookie that is part of the current request,
use
Note that cookie values cannot include white space or semicolons.
If you are building a cookie value dynamically, it is recommended that you
URL quote it, which will remove all these values.
For example, set the cookie to a value
with
The set-cookie syntax is as follows.
Because of various browser bugs, you must specify the path.
The date string is formatted as:
expires is an optional attribute. If not specified, the cookie will
expire when the user's session ends. Note: many browsers do not work
with 4-digit years. Wdy, DD-Mon-YY HH:MM:SS GMT appears to work everywhere,
even though the specification is for a 4-digit year.
Note: There is a bug in Netscape Navigator version 1.1 and earlier.
Only cookies whose path attribute is set explicitly to "/" will
be properly saved between sessions if they have an expires
attribute.
Only hosts within the specified domain
can set a cookie for a domain and domains must have at least two (2)
or three (3) periods in them to prevent domains of the form:
".com," ".edu," and "va.us." Any domain that fails within
one of the seven special top level domains listed below only require
two periods. Any other domain requires at least three. The
seven special top level domains are: "COM," "EDU," "NET," "ORG,"
"GOV," "MIL," and "INT."
For example, domain=.abc.com (note the 2 dots) will set the domain tail
so that xxxx.abc.com is matched.
The default value of domain is the host name of the server
which generated the cookie response.
If secure is not specified, a cookie is considered safe to be sent
in the clear over unsecured channels.
To find the correct template, Web Crossing first checks the templates assigned to
the current folder. If not found, then the parent folder is checked, and so on to the
top-level. If still not found, then the top-level of the
webx.tpl and webxextn.tpl files are checked. If
still not found, then the sysop panel templates are checked.
To override the templates for a folder, use the following steps:
You can include files into webx.tpl by using the following directive:
Whenever a WCTL page evaluates to text starting with "HTTP/," that page
is returned as is, without adding the normal HTTP response heading.
For example, the following template forwards the request
...WebX?forward@@ to a discussion.
HTTP/1.0 302 Redirect is the standard first line for a response
from a Web server to the user's Web browser. This one has a response code
of 302, which asks the browser to temporarily forward the original URL to
a new location.
Location:... is the fully-qualified URL to which to forward.
Note that the response must end with a final blank line.
HTML documents include formatting and other directives.
For example,
SGML quoting converts all of the HTML special characters (<, >, etc) to their
quoted format (<, >, etc).
The result is a text string that displays exactly as
the original text.
If you "SGML quote" the sample text in an HTML document
to
URL quoting takes the actual pathname and replaces special URL characters with
a percent sign and 2 hexadecimal digits (e.g. blanks are replaced with %20).
For example, in a URL,
In WCTL, most values are automatically quoted. For example,
%% userName %% is SGML quoted, and
%% parentUrl %% is URL quoted.
You can explicitly control SGML and URL quoting in Web Crossing. For example,
%% userName.fromSGML %% is the original user name without SGML quotes.
See the string functions in the
WCTL Built-in Variables document for a list of available conversions.
For example, suppose you need to get the e-mail address of a user from an external database.
You can run a script to obtain this from the external database, and then embed this information
into the current page. You might use
The server-side include directives for Web Crossing are:
The results from exec, cgi, or file can be multiple lines long, they
are not restricted in any way.
Also, the results of exec, cgi, or file can also be stored
into a variable for use as desired. For example,
The first line of the message is the list of users, and the remainder of the message
is a normal e-mail message including the full heading. For
example,
Filter macros can examine form fields and take appropriate action:
build a complete page to send to the user,
forward the user to a different URL,
construct an error message,
evaluate to a user ID for the registered user, or
evaluate to a blank page for normal processing.
For example, the following macro will check a registration post
for objectionable words, and evaluates to an error message to be displayed
if there is a problem:
Web Crossing supports using multiple registered filter macros. For example, if you wanted to run another authenticateFilter macro besides the standard one, you could do a % % "authenticateFilter".filterRegister("authenticateFilter_xxx" ) % % All filters can have additional macros registered. Additional macros are called in the order they are registered.
This macro outputs one of the following:
This macro outputs one of the following:
This macro outputs one of the following: If the filter macros are present, when called they initiate the following sequence:
"Pre" filters are called before the add or edit is processed;
To call JavaScript from WCTL use the jsCall directive with string parameters. For example
This is the same as using
but avoids the parsing overhead of the older jsEval directive so is significantly faster.
To call JavaScript from WCTL you may also use
to evaluate a JavaScript script. For example,
will call JavaScript and evaluate to "3." The value of the JavaScript expression
is converted to a string and returned as the value of jsEval. This method offers no advantage over jsCall and is significantly slower.
» Using the Web Crossing Template Language
The Web Crossing Template Language (WCTL) may be used
anywhere that the sysop or conference host enters HTML text.
For example,
Title: <b>%% pathTitle %%</b>
might display as
Title: General Interest
%% username %% is the same as
%%username%% or
%% username%%
<a href="xxx">%% nop %%
<img src=yyy></a>
would be output as
<a href="xxx"><img src=xxxx></a>
» Built-in variables
Web Crossing provides a number of built-in variables.
These variables let you insert information into the text served
to your user. They also let you check for various conditions,
and to customize served text based on these conditions.
%% if user2ndLine %%
<p>Other information: %% user2ndLine %%
%% endif %%
%% set i 50 %% -- sets i to 50
%% i %% -- evaluates to 50
%% set i i + 1 %% -- sets i to (i+1)
%% i %% -- evaluates to 51
%% set i "abc" %% -- sets i to "abc"
%% i %% -- evaluates to abc
%% set i i + 1 %% -- sets i to (i+1)
%% i %% -- evaluates to 1
%% "abc" & "def" %% -- catenates the strings to evaluate to abcdef
%% "abc" + "def" %% -- adds two numbers to evaluate to 0
» Substitutions
All of the built-in variables can be used to substitute text into the
HTML output sent to the user. For example, %% userHomePage %%
will add a URL to the user's home page (or an empty string if this has
not yet been entered by the user).
%% if userIsSubscribed %%
subscribed
%% else %%
not subscribed
%% endif %%
will add subscribed or not subscribed to the page.
» Expressions
You can use expressions in WCTL.
The operators are the same as in C/C++/Java,
except that the ampersand (&) is used for string concatenation.
For example,
%% 10 % 7 %% -- evaluates to 3
%% (10+45) % 7 %% -- evaluates to 6
%% "abc" & 0 %% -- evaluates to "abc0"
%% 5 & 6 %% -- evaluates to "56"
Operators Use + - unary plus and minus * / % & times, divide, modulus, string-catenate operators + - plus or minus operators < <= > >= less-than, less-than-or-equal, greater-than, greater-than-or-equal comparison == != equal and not-equal comparison && logical AND || logical OR () in an expression » Constants
Constants can be numbers or string.
» Defining your own variables
WCTL lets you define your own variables.
You can define temporary variables in a template,
or permanent variables that are stored as fields in the Web Crossing database.
If you reference any variable before you set it,
its value is the empty string.
Variable Usage Scope varName Local variable. Once you set a local variable it
can be referenced from any template in the current execution,
not just the one that set it.
Local variables are always cleared before evaluating a new template or
sysop template.
To keep a value around from page to page, use a user-record variable,
a current-location path variable, or a global site variable.
%% set currentAd "General Rotation" %%
<img src=http://mysite/%% currentAd %%>
session.varName Session variable. These variables are
kept for each user session.
user.varName User variable.
User variables are stored in the database as an additional field in the user record,
so they are saved with the database and are available as a permanent part
of the user's record.
%% set user.phone form.phone %%
Your phone number is now: <b>%% user.phone %%</b>
<input name=user.phone type=text value="%% user.phone %%">
to your editPreferences template will allow users to edit their
phone number in their personal preferences page.
author.varName Author variable. Same as a user variable, but in the
user-record for the author of the current location.
Phone number: <b>%% author.phone %%</b>
You can set the current author through the setAuthor function.
path.varName Path or location variable, defining an additional
field for the current location.
Path variables are stored in the database as an additional field for
any folder, discussion, message, link, or chat room, and are saved with the database.
%% set path.totalHits path.totalHits+1 %%
In the templates that add or edit a location (addFolder, editFolder,
addDiscussion, editDiscussion,
addMessage, editMessage, addChat, editChat,
addLink, and editLink),
you can use these variables as the name of an input field, and Web Crossing
will automatically set them for you when it processes the form.
For example, adding<input name=path.title type=text value="%% path.title %%">
to your addMessage and editMessage templates will allow users to specify
a title for the message. (For this example, you could also customize
the messageListItem
template to show the title as part of the message display).
If there is no current location, path$varname uses the top-level folder.
Location path.xxxx path$xxxx Folder 1 "abc" "abc" Folder 1/Folder 2 "" "abc" (from Folder 1) Folder 1/Folder 2/Discuss "def" "def" site.varName Global site variable, defining an
additional field for the global site information. Site variables are saved with the database.
%% set site.sysopPhone form.phone %%
The sysop phone number is now: <b>%% site.sysopPhone %%</b>
» Scope of variables
User-defined local variables such as x are defined for the
current execution chain:macro: m1 m2 m3
calls: use m2 ->
set x 1
use m3 ->
x == 1
endmacro
x == 1 <-
endmacro
x == 1 <-
endmacro
Outside of this context, x will be "", the default.
» Conditional sections
WCTL supports conditional sections. For example,
%% if 1 %%
TRUE
%% else %%
FALSE
%% endif %%
TRUE
if awayhours > nnn
to check for the last
login having been more than "nnn" hours ago, or
if lastLogin < mm/dd/yyyy.hh:mm:ss
to check whether the prior login
was before a particular date.
» Setting persistent variables
You can set persistent variables (session.xxxx) variables for both guests and logged in users.
These session variables allow user state to be tracked across multiple requests/pages. The syntax is
%% set session.name value %%
(save a string or number into a session variable.)
%%... session.name ...%%
(return the current value of a session variable,
or the index of a saved container for use in subsequent scXxx calls.)
» While loops
A while loop lets you repeatedly cycle through the same instructions
while a condition is true.
For example, you can process all the entries in a list of user posts:
%% set posts user.userposts(5) %%
%% set post posts.split %%
%% while post %%
%% setPath(post) %%
%% pathDate %%<br>
%% set post posts.split %%
%% endwhile %%
This while loop iterates over a list of up to 5 most recent posts by the current user,
and displays the date for each post. userposts(5) returns the 5 most recent posts
as location unique IDs. posts.split returns the first blank-delimited location, and sets
posts to the remaining locations. setPath(post) sets the current location,
so pathDate can display its date.
%% set start -1 %%
%% while 1 %%
%% set start start+1 %%
%% if start >= 100 %%
%% break %%
%% endif %%
%% if start % 2 == 1 %%
%% continue %%
%% endif %%
%% start %%-
%% endwhile %%
» Macros
A macro is a named piece of text defined in the webx.tpl file.
A macro can include both HTML text and WCTL expressions.
For example,
%% macro testMacro %%
Hello World on %% date %%.
%% endmacro %%
%% macro folder %%
...layout for folders...
%% endmacro %%
%% macro greetingNews %%
Hello %% userName %%.
%% endmacro %%
will set the sysop Greeting
template to Hello %% userName %%.
%% macro realAudioSource %%http://mysite.com/audio.ram%% endmacro %%
... %% use realAudioSource %% -- will insert the correct URL
» Calling another macro
You can call another macro with the use directive. For example,
%% use greetingNews %%
would insert the current greeting template into the output text.
% % macro level1 % %
% % macro level2 % %
% % macro level3 % %
...
% % endmacro % %
% % endmacro % %
% % endmacro % %
% % macro test % %
% % use nested // calls 1 % %
» Queueing a macro for later execution
You can queue a macro for later execution (i.e. similar to chron on Unix).
%% "macroname".queue( delay, param1, param2 ) %%
where param1 and param2 default to none, and where delay is in milliseconds and defaults to 0. For example, %% "backgroupCheck".queue( 3600000 ) %% will run the "backgroupCheck" macro every hour.
%% qParam1 %%
%% qParam2 %%
get the startup parameter strings for a queued macro.
(I.e. When the queue macro runs the built-in qParams variables get set to the qmethod specification.)
» Return statement
You can return from a template at any point with the return statement.
For example,%% if i > 50 %%
%% return %%
%% endif %%
The return statement causes an immediate exit from the current macro.
In an ordinary template, this terminates the output page and evaluation of expressions.
If the current macro was executed via a %%use%% statement, control returns to the
statement following the %%use%%.
» Creating your own pages
You can create your own pages associated with a location parameter in a
Web Crossing command. You can use this to show alternative views, to split
user preferences into multiple forms, etc.
%% macro yourMacro_ %%
...HTML and template expressions for your page...
%% endmacro %%
» Forcing a user login
Template macros do not require the user to be logged in.
%% if userIsUnknown %%
%% return %%
%% endif %%
» Processing forms
You can use WCTL to process forms and update variables stored in the Web Crossing
database. For example, you could take a survey or extend the built-in
user directory with additional fields.
<form method="POST" action="%% urlBase %%myFormProcess@%% certificate %%@%%location%%">
» CGI environment variables
You can access CGI environment variables in the Web Crossing Template Language.
For example,envir.query_string
is the complete query string from the URL for the current request.
...?showEnvir@@
to see a list of variables and their values.
(The showEnvir template uses the envirList WCTL variable to get a list of all the
CGI variables, then iterates over this list to display each variable name and its value.)
» Using cookies in WCTL
Using WCTL, you can send cookie values to the client, and get cookie values sent
from the client as part of the current request.
%% addResponseHttp( "Set-cookie: abc=xxx; path=/" ) %%
This will set a cookie named abc to the value xxx.
%% envirCookie( "abc" ) %%
This will access the value of the cookie named abc.
%% addResponseHttp( "Set-cookie: abc=" & value.toUrl & "; path=/" ) %%
and get the value
with%% set value envirCookie( "abc" ).fromUrl %%
Set-Cookie: NAME=VALUE; path=PATH;
expires=DATE; domain=DOMAIN_NAME; secure
Note that Macintosh IE5 requires that path be specified before expires in order to work correctly..
Wdy, DD-Mon-YYYY HH:MM:SS GMT
» Using templates on a folder-by-folder basis
You can assign template macros on a folder-by-folder
or discussion-by-discussion basis.
This allows you to customize the look of a specific set of folders or discussions.
%% macro yourFolderMacro %%
%% macro folderListBefore %%
...your HTML text to insert before the folder's item list...
%% endmacro %%
%% macro folderListItem %%
...your HTML text to customize each folder item...
%% endmacro %%
%% macro folderListAfter %%
...your HTML text to insert after the folder's item list...
%% endmacro %%
%% endmacro %%
» Include files for webx.tpl
<!--#Include File="filename.tpl"-->
where filename is the file to include. You must use this syntax exactly: spaces, capitalization, and all.
Included files may have any suffix in the filename, but ".tpl" and ".js" are recommended for WCTL files and
WCJS files respectively. Files with names ending in ".auto" are automatically included just before the webxextn.tpl file;
in other words, they will be included whether or not they are specifically included via the #Include syntax.
Include files may be included conditionally, the conditional syntax is:
<--#Include File="filename.tpl" if="expr"--> or
<!--#Include File="filename.tpl" if='expr'-->
where expr is any WCTL expression, and is not sgml-quoted. Files that need to be included
may be accumulated and then included just one time:
<#--Include File="filename.tpl" Later-->
will add filename to a list to be added later. If the filename is already on the list of pending files
for "Later", it will not be added again, so files are only included one time.
<!--#Include Now-->
will include all the accumulated "Later" filenames at this point, and will reset
the "include later" list to empty. Note that this means that the same file could be included
more than once if you have multiple "include-later"/"include now" sequences. You can use a
conditional to check to see if a file has already been included:
<!--#Include File="filename.tpl" IfNotAlreadyLoaded-->
If the file has already been loaded, or is in the "include later" list, then it is not loaded;
otherwise it is loaded. This directive allows multiple include files that all depend on some
other file to only include the required file one time.
Web Crossing writes a file named webxIncludes.log showing include files after startup
and each template/cache reset. Indents are used to show nesting. » Forwarding URLs, and other HTTP responses
Web Crossing allows you to forward requests to another URL, and in general, to
return any HTTP response.
%% macro forward %%
HTTP/1.0 302 Redirect%% crlf %%
Location: http%% if siteIsSecure %%s%% endif %%://%%siteHost%%
%%urlBase%%14@%%alwaysCertificate%%@%%location%%%% crlf %%%% crlf %%
%% endmacro %%
A carriage-return/linefeed is added to the end of each line by the
built-in crlf variable. Because Web Crossing strips trailing
newlines following an expression (e.g. following %% crlf %%),
you can write the response on multiple lines for readability, without
having extra newlines inserted into the result.
» SGML and URL quoting
In order for text to display exactly as intended in the user's Web browser,
you sometimes need to be aware of the quoting conventions used in HTML.
<b>Sample text</b>
will display asSample text
in the user's Web browser.
<b>Sample text</b>
then it will display exactly as the original.
My pathname
becomes My%20pathname
» Server side includes: scripting and using external files
You can call external programs and use the values they return (on Unix and Windows).
E-mail address: %% exec( "getEmail " & userName ) %%
to run an external program named getEmail, with a command line of something
likegetEmail Smith, Bob
The output of this program is inserted into the page being prepared by WCTL.
exec( commandLine )
Run a program with the specified command line, and return the output from the program.
For example, exec( "myProgram" ). cgi( commandLine )
Run a program with the specified command line, and also set all the environment
variables from the current CGI request.
For example, cgi( "myCgiProgram" ). (See the section on . scriptError
The error message for the last exec or cgi program, or the empty string if no error.. fileError
The error message for the last file include, or the empty string if no error.. %% set address exec( "getAddress " & userName ) %%
will store the result of running something
likegetAddress Smith, Bob
into the variable address.
» Sending e-mail messages
You can send email messages from WCTL by using the email
command. This requires that the "Domain name server" field on the General
Settings control panel be set correctly for your site. (Note: the Web
Crossing server must be restarted when this field is set or changed.)
%% set _message
"<" & user.userEmail & ">" & crlf &
"To: " & user.userName & " <" & user.userEmail & ">" & crlf &
"From: Web Crossing Admin <" & sysopEmail & ">" & crlf &
"Subject: Welcome to Web Crossing" & crlf & crlf &
"Thanks for joining the " & siteTitle & " online community..." & crlf %%
%% email( _message ) %%
will compose a welcome message and mail it to a newly-registered user. Note that the "To:" field
is not used to send the message: The message is actually sent to each user in the first line,
and the first line is not included in the message. You can send to multiple users by
including them in the first line, separated by commas,
such as <user1>, <user2>.
» Filter macros
Web Crossing allows you to filter authentication, login, registration and user-preferences changes,
so that you have total control over these actions.
%% macro registerProcessFilter %%
%% if form( "username" ).isObjectionable %%
The user name is not allowed.
%% else if form( "email" ).isObjectionable %%
The email address is not allowed: %% form( "email" ).markObjectionable %%
%% endif %%
%% endmacro %%
In this example, if either the username or email form fields contain objectionable text, an error message is added to the macro output. This will cause the registration form to be redisplayed for the user to remove the objectionable text. If there are no objectionable words, the macro evaluates to all white space, and processing continues normally.
The WCTL calls for registering filter macros are:
Filter registration directive Usage filter.filterRegister( macroName )
Adds an additional filter filter.filterDeregister( macroName )
Removes a filter filter.filterList
Returns the current filter registration list filter.filterClear
Clears the filter registration list
For macros that can return a new user ID, such as registerProcessFilter, the new user ID becomes the "current user" for any additional filter macros that have been registered to run.
If a filter can return a full page to be sent to the user, returning a page stops processing of the registered filters, and the page is returned immediately.
If a filter can return an error string, then error strings are accumulated automatically for the various macros (separated by "<br>"). But if a full page is returned by a later registered filter, then the accumulated error messages are just discarded.
Filters are also useful in processing forms. Any input form may have hidden "filter" fields that specify the suffix for additional processing filters. The base filters will always be run as well. For example, if the form for adding a folder contains:
<input type=hidden name="filter" value="blog">
<input type=hidden name="filter" value="accounting">
then the processing will do the following:
use addFolderPre
use addFolderPre_blog
use addFolderPre_accounting
... process the form, add the folder, etc ...
use addFolderPost_accounting
use addFolderPost_blog
use addFolderPost
Since you can have multiple filters on the same form, you can add a section to a form and put your processing filter in that section as well.
Note that you could register additional macros to be called right after addFolderPre, or after addFolderPost, in addition to the form-based filter specs.
The combination of registered filters, input form filters, localized filters via the template envelope for a given location, and localized WCJS filters for a given location makes it possible to add specific, highly targeted functionality as needed for new/customized objects.
The available filters are:
Filter macro Usage authenticateFilter
If present, called after the normal WebX authentication,
before processing the request. The user variable is set to the
user as authenticated by Web Crossing.
The original request including the certificate is available through
envir.query_string, and any cookies are available through
envirCookie( "cookieName" ).
loginFilter
If present, called after the normal WebX login,
before processing the login actionPath. The user variable is set to the
user as authenticated by Web Crossing.
The original request including the certificate is available through
envir.query_string, and any cookies are available through
envirCookie( "cookieName" ).
loginAuthenticateFilter
If present, called to authenticate NNTP logins. It is similar to the authenticateFilter,
except that it is used for NNTP logins exclusively. If this filter evaluates to a user ID
(same format as authenticateFilter), then that user is logged in and the filter returns a page
that contains the userID; other wise it returns an empty page. Any other return will
treat the user/password as invalid and will not login any user. This
filter is used in places where the response may not be in HTML, such as the NNTP login,
so it can't return an HTML page on an error, it can only indicate that the user
login is not allowed.
This macro has available 3 WCTL directives: loginUsername (the username),
loginPassword (the password) and loginProtocol (parameter) which accepts
the parameters "httpForm", "httpBasic", "pop3", "imap", "wctl", "wcjs" for
HTTP form, HTTP Basic, POP3, IMAP, WCTL, and WCJS logins. There are no filters for
POP3 APOP or for HTTP Digest mode.
loginFailureFilter
If present, called after the normal WebX login fails. If the user exists but
the password was wrong, then the user variable is set.
The original request including the certificate is available through
envir.query_string, any cookies are available through
envirCookie( "cookieName" ), and the login form fields are available through
form.username and form.password.
moderatedAddFilter
If present, that is called if present for all moderated posts just after they are added to
the moderated queue. In this filter, there are two values that provide info about the moderated
item just added. addModeratedType is the type of item added: folder, discussion, message, or
nntp (nntp is a moderated message that is posted via email or nntp). addModeratedItem is
the moderated item number, and can be used to add custom fields to the moderated item, etc.
If the moderatedAddFilter returns a non-blank page, then that page is returned to the user instead
of the normal response. (Obviously, for NNTP/email, any returned page is just discarded.)
A sample test filter is:
% % macro moderatedAddFilter % %
Moderated item % % addModeratedItem % % of type % % addModeratedType % %
% % endmacro % %
registerProcessFilter
If present, this macro is called before processing a registration form.
It evaluates to one of the following:
The requesting user is available for the registerProcessFilter. The current user in this filter will be either userIsUnknown (e.g. user registration) or userIsSysop (e.g. sysop manual registration).
registerFailureFilter
If present, this macro is called after processing a registration form,
when the registration request had some error.
It evaluates to one of the following:
preferencesProcessFilter
If present, this macro is called before processing a user-preferences change.
It evaluates to one of the following:
httpBasicNewFilter
If present, this macro is called when HTTP basic authentication is turned on,
and the incoming user is not in the Web Crossing user directory.
It evaluates to one of the following:
folderAddFilterPre
folderAddFilterPost
folderEditFilterPre
folderEditFilterPost
discussionAddFilterPre
discussionAddFilterPost
discussionEditFilterPre
discussionEditFilterPost
messageAddFilterPre
messageAddFilterPost
messageEditFilterPre
messageEditFilterPost
chatAddFilterPre
chatAddFilterPost
chatEditFilterPre
chatEditFilterPost
linkAddFilterPre
linkAddFilterPost
linkEditFilterPre
linkEditFilterPost
webAddFilterPre
webAddFilterPost
webEditFilterPre
webEditFilterPost
These filters permit creating and editing tasks for folders, discussions, messages, links, chat rooms, and web pages.
"Post" filters are called after the add or edit, but before the normal display of the results.
»
Read/write a file.
The following commands permit you to read/write a file:
filename.fileExists
Return 1 if the filename exists, such as
%% if "testfile".fileExists %%
filename.fileLength
Return the length of the file, or "" if no such file
filename.fileRename( newname )
Rename the file to the newname, such as
%% "testfile".fileRename( "testFile2" ) %%
filename.fileDelete
Delete the file
filename.fileRead( offset==0 , length==wholeFile )
Reads data and returns it as a string.
By default, reads the whole file.
filename.fileWrite( data, offset==endOfFile )
Writes data into a file. Creates the file
if it does not exist.
By default, appends data to the end of the file, but can also
be used to overwrite existing data.
» Calling JavaScript from WCTL
You can call JavaScript functions from WCTL. See the documentation on
server-side JavaScript for a description of how to write
JavaScript functions in Web Crossing.
"lang".jsCall( "extn", "btnok" )
"lang( 'extn', 'btnok' )".jsEval
string.jsEval
%% "1+2".jsEval %%
» Calling a template macro
from TCP/IP
You can call template macros from WCTL using the TCP/IP Direct Access Protocol. See the documentation on
RUN/MACRO:/QPARAM1:/QPARAM2:
for a description of how to do this. You can also call macros with the open protocol XML-RPC, which
is supported by a wide variety of programming languages, but this feature requires use of the
Web Crossing JavaScript implementation.
Two functions allow you to issue an HTTP request and wait for the response:
%% set httpDataFromServer url.http( timeout==30 ) %%where "url" is the full URL to GET, such as %% set webx "http://webcrossing.com/new302/compare.shtml".http %%. This function returns the response to the HTTP request, or an error message starting with an '*'. The timeout is in seconds and defaults to 30 seconds.
%% set httpDataFromServer url.httpReq( request, timeout==30 ) %%where "url" is the address of the HTTP server, and "request" is a fully-formatted HTTP request including all CR/LF characters. The timeout is in seconds and defaults to 30 seconds. This allows you to generate a POST or other requests. For example, %% "http://ipAddress.com/".http( "GET /xxxx?abc HTTP/1.0" & CRLF & CRLF ) %%.
The data is returned from the HTTP server, or an error message starting with a '*'. Error messages returned by url.http/url.httpReq:
* Http request timeout
-- Connection timeout
* Can't create connection
-- Connection was refused or to many outstanding connections
* Connection error: xxx
-- Connection was dropped
* Bad response
-- The response doesn't contain html data
* Server response code: xxx
-- URL error, i.e. "404 not found"
Both the url.http and url.httpReq command allow you to fetch and post
pages from/to secure servers, by specifying https: in the URL.To just link to a folder or discussion, you can go to that location in your Web browser, copy the URL of the location, and delete the text between the at (@) signs. For example,
http://webcrossing.com/webx?14@0.ag4d3fde^0@/Test
would be edited to
http://webcrossing.com/webx?14@@/Test
for use in a link you are building.
http://your_site/<access path>[?<command>[L]@<certificate>@<parameters>]
where [...] is an optional component.
| <access path> | is the name of the CGI script or other interface between Web Crossing and your Web server. |
| <command> | is either a command code or a template you have defined. |
| L | if the command code is followed by L, the user will be asked to login. (This option is not available for pages you have defined.) |
| <certificate> | is used to identify the current user and includes a sequence number to force a user's client to fetch new information instead of using old cached material. |
| <parameters> | is additional information required for a command.
This is almost always the location in the conference to which a command applies. The location may be a folder, a discussion, or a message in a discussion. |
If the command is omitted entirely, then Web Crossing uses the default command you entered in your Banner, footer, background, and top-level page appearance panel, or to the top-level folder.
...?command@cert@location!name=value&name=value...The names and values must be URL-quoted, so that blanks, & and equal signs in the names/values don't get confused with the name=value& syntax. For example, if a value was "abc def," then it would be "abc%20def" in the URL.
In WCTL, you reference these additional parameters by using
form.namejust as if the name=value from the URL had been in an input form.
For example, try the URL
...?testMacro@@!name=abcwith a testMacro in your webx.tpl file:
%% macro testMacro %%
Name=%% form.name %%
%% endmacro %%
If there are more than one set of name=value for the same name
(in the URL and input form combined), then the last value is returned by
form.name (with the URL checked first, then the input form).
This allows usage like the following:
<input type=hidden name=myCheckbox value=false> <input type=checkbox name=myCheckbox value=true>The browser only sends a "myCheckbox=true" for the checkbox input field when that checkbox is checked. So with the hidden field, you will have form.myCheckbox=="false" if the checkbox is not checked, or form.myCheckbox=="true" if the checkbox is checked.
../webx/location/macroOrCmd/cert.certificate/name.value[/name.value.. .]versus the query-string format of
.../webx?macro@certificate@location!name=value[&name=value...]For example,
.../webx/.ee7b94d/1/testCmd/cert.242.UI9aaaDBts6^1/lookup.falseis now the same as
.../webx?testCmd@242.UI9aaaDBts6^1@.ee7b94d/1!lookup=falseIn both syntax formats, the name and value items must be URL quoted, and the certificate can be omitted (you can omit the entire "/cert.certificate" from the new syntax). In the new syntax, you can use "cmd.nnn" for the command code of nnn. For example,
.../webx/testing/cmd.14is now the same as
.../webx?14@@/testing(where "/testing" specifies a folder named "testing").
Commands typically apply to a Command Codes document for a complete listing of available codes.
Certificate syntax is:
[<slot>.][<userkey>][^<seqno>]
where [...] is an optional component.
| <slot> | is a number from 0 to 999, and is the slot assigned to this certificate. |
| <userkey> | is omitted for an unknown user, or is 8 random characters for a registered or guest user. This random user key is used to identify the user, and authorizes his/her access. The userkey is assigned at the time the user logs in or registers. The userkey is valid for a timeout period, usually 30 minutes, and expires automatically if the user doesn't issue another request during the timeout period. |
| <seqno> | is a number starting with 1 that is incremented for each response, and is used to make the client side fetch new pages instead of showing an old cached page. |
For example, the following table shows some possible certificates:
| Certificate | Usage |
|---|---|
| 0.abcxyzaa^1 | A typical certificate for a logged-in user. |
| 0.abcxyzaa^2 | A typical certificate for a logged-in user. |
| An empty certificate for first-time entry | |
| ^243 | A typical unknown user with guest access. The sequence number is used to force the user's browser to fetch current pages. |
Folder pathnames may use folder titles, such as /Books, or the unique ID of the folder, such as .aef345. Note that long titles may cause errors in your HTTP server.
Discussion pathnames may be either a folder pathname and discussion ID number, such as /Books/3, or the unique ID of the discussion, such as .aef34a. (Discussion IDs are assigned starting from 1 and are not reused if a discussion is deleted.)
Individual messages are located by their discussion pathname and message ID. For example, /Books3/22 or .aef372/22. (Message numbers are assigned starting from 0 and are not reused if a message is deleted.)
The location pathname must use URL quotes. For example, blanks must be replaced by %20, as in /Books%20in%20Russian/3.
<b><a href="%%siteUrl%%">The Best Place</a></b><br> <b>Forum: <a href="%% parentUrl 1 %%">%% parentTitle 1 %%</a></b> %% if pathIsFolder %% <p> %% else %% <br><b>Topic: <href="%% parentUrl 2 %%">%% parentTitle 2 %%</a></b><p> >%% endif %%
This might display as:
<a href="%% pathUrl %%">
%% pathIcon border=0 align=bottom%%
<b>%%nop%%
%% pathTitle %%
</b>%%nop%%
%% if pathHasMessages %%
<font size=2>(%%nop%%
%% pathMessageCount %%
%% if pathHasOneMessage %%
message%%nop%%
%% else %%
messages%%nop%%
%% endif %%
%% if pathHasNewMessages %%
,%%nop%%
%% pathNewMessageCount %%
new %%nop%%
%% endif %%
)</font>%%nop%%
%% endif %%
</a><br>
Note how this template is made more readable by using %%nop%% to suppress newlines in the output. (This works because Web Crossing removes newlines that immediately follow a variable. The indents in this example should be replaced by tabs if you copy this for your use (again, because Web Crossing strips leading tabs to help make the template more readable).
You can see some of the various substitution values by going to the Folder appearance control panel and setting the HTML template for each item in a folder to the following:
<a href="%%pathUrl%%">link</a><br>
title - %% pathtitle %%<br>
url - %% pathurl %%<br>
icon - %% pathicon align=top %%<br>
has messages - %% pathhasMessages %%<br>
one message - %% pathhasoneMessage %%<br>
message count - %% pathmessagecount %%<br>
new messages - %% pathhasnewmessages %%<br>
one new message - %% pathhasonenewmessage %%<br>
new message count - %% pathnewmessagecount %%<br>
created by sysop - %% pathcreatedbysysop %%<br>
creator name - %% pathcreatorName %%<br>
creator URL - %% pathcreatorURL %%<br>
created date - %% pathcreatedDate M2D2Y2%%<br>
created date default - %% pathcreatedDate %%<br>
modified date - %% pathModifiedDate M2D2Y2 %%<br>
modified date default - %% pathModifiedDate %%<br>
path is none - %% pathisnone %%<br>
is folder - %% pathisfolder %%<br>
is discussion - %% pathisdiscussion %%<br>
is top - %% pathistop %%<br>
date - %% date M2D2Y2%%<br>
date default - %% date %%<br>
time - %% time H2I2 %%<br>
time default - %% time %%<br>
<pre>
12345%%pad 10%%xx
12345%%pad 2%%67890
12<b>34</b>5%%pad 10%%xx
</pre>
is unknown - %% userIsUnknown %%<br>
is sysop - %% userIsSysop %%<br>
is host - %% userIsHost %%<br>
is guest - %% userIsGuest %%<br>
is registered - %% userIsRegistered %%<br>
certificate - %% certificate %%<br>
creator line 2 - %% pathcreatorLine2 %%<br>
site title - %% sitetitle %%<br>
site URL - %% siteUrl %%<br>
parent URL - %% parentUrl %%<br>
back path - %% backpath %%<br>
serve pictures - %% servepictures %%<br>
serve info pictures - %% serveInfoPictures %%<br>
version - %% version %%<br>
platform - %% platform %%<br>
newdiscuss - %% newdiscuss %%<br>
%% if pathIsTop %% ...your normal text, including links into the conference... %% else %% Please log in. %% endif %%
The result is that when a user logs in and they are going to the top level, they will see your normal login heading. If they follow a link from that login page, they will be going to a specific place, and will just see the "Please log in" heading.