WebSiphon 2 Guide: SiphonScript Functions
contents prev next

  1. Calling Functions
  2. Defining Functions
  3. Output Streams
  4. Function Libraries
Calling Functions

Functions in SiphonScript are called using a C-style syntax: the function name followed by a list of parameters separated by commas, enclosed in parenthesis. Even if a function has no parameters, the parenthesis are required when performing a function call. As with other statements in SiphonScript, a function call always ends with a semicolon.

If a function has a return value, it may be included in any expression such as a parameter to another function.

Examples:

  1. // A simple function call used to redirect a web browser to a
    // different URL, found in the collection of Internet functions
    redirectClient("http://www.apple.com/");
  2. // This function call returns a list of available Verona 
    // databases. Using a standard variable assignment, the 
    // variable db_list now holds this information.
    db_list = vGetDatabases();
  3. // Here we are defining a standard list, but the items 
    // in the list are actually the returned results of two
    // function calls.
    my_list = [currentDate() currentTime()];
Defining Functions

In addition to using the large suite of built-in functions available with WebSiphon, you may define your own functions using SiphonScript.

The form of a function definition is:
[stream] function FunctionName([param1 [, param2 [,... paramN]]])
  ...
end [function];

The parameter list is optional, and can contain zero or more parameter names separated by commas. The function keyword following end is also optional. The stream keyword is fully described in the section below.

One of the common uses for functions in WebSiphon is to make it easier to print common page elements, such as headers and footers, with a single statement. An example page footer function is shown in the example template below.

Example Template:

<<

  // My company's standard site footer
  function MyPageFooter
    <<
    <HR>Copyright (c) 1998 My Company</BODY></HTML>
    >>
  end function;
  
>>
<HTML>
<HEAD>
<TITLE>My Company's Home Page</TITLE>
</HEAD>
<BODY>
<H1>My Company's Home Page</H1>
<HR>
Welcome to our home on the Web!
{MyPageFooter()}

Resulting HTML:

<HTML>
<HEAD>
<TITLE>My Company's Home Page</TITLE>
</HEAD>
<BODY>
<H1>My Company's Home Page</H1>
<HR>
Welcome to our home on the Web!
<HR>Copyright (c) 1998 My Company</BODY></HTML>

The example below demonstrates how to create a function that can accept a parameter, and will yield different results depending on what is passed in the page_title parameter.

With both MySiteHeader() and MySiteFooter() included in a template (or included as a component to a script library - see below), you can insert the standard site header and footer in any HTML document as is shown in this last example.

Example Template:

<<

  // My company's standard site header
  function MyPageHeader(page_title)
    <<
    <HTML>
    <HEAD>
    <TITLE>{page_title}</TITLE>
    </HEAD>
    <BODY>
    <H1>{page_title}</H1>
    <HR>
    >>
  end function;

  // My company's standard site footer
  function MyPageFooter
    <<
    <HR>Copyright (c) 1998 My Company</BODY></HTML>
    >>
  end function;
  
>>
{MyPageHeader("My Company's Home Page")}
Welcome to our home on the Web!
{MyPageFooter()}

Resulting HTML:

<HTML>
<HEAD>
<TITLE>My Company's Home Page</TITLE>
</HEAD>
<BODY>
<H1>My Company's Home Page</H1>
<HR>
Welcome to our home on the Web!
<HR>Copyright (c) 1998 My Company</BODY></HTML>

Return Values
As with built-in functions, user-defined functions can have return values. By default, all user-defined functions have a default return value of null. This means that any function can be called as part of an expression, even if it does not explicitly specify a return value. The return statement is used to specify a function's return value.

Here is a simple function that returns a value based on the parameters passed to it:

  function SimpleFunction(a, b)
    return a + sqrt(b);
  end function;
Output Streams

Script functions have the very powerful ability to work with the output streams generated by print statements and HTML blocks. There are two ways to do this: include the stream keyword in a function definition, or use the stream keyword (or "$" character) as a modifier to a function call, placed before the function identifier.

To demonstrate how this works and why you would use it, assume that we have a function named MessageBox(). It's purpose is to create a small HTML table that can be used for displaying any message, such as an error.

function MessageBox(title, contents)
  <<
  <center><table border="1" width="60%"><tr>
  <th bgcolor="dddddd">{title}</th></tr>
  <tr><td align="center">{contents}</td></tr></table></center>
  >>
end;

Now assume that we want to include the output of another function as the message box contents. Normally we would have to build a large string and concatenate bits and pieces onto it, which is complicated and hard to read. But if we used an HTML block, for example, the text would just be appended to the output stream and we couldn't place it inside the table.

Here is a very simple function:

function TestMessage
  repeat with i from 1 to 10
    print i;
  end;
end;

Without streams, there would be no way to pass the output of TestMessage() as the contents parameter of MessageBox(). But using streams, this is quite easy.

The first method uses the stream keyword, or the "$" character for shorthand, as a modifier for the function call itself. So, creating a message box with the text output by TestMessage() would look like:

MessageBox("Important Announcement!", stream TestMessage());
or, using shorthand,
MessageBox("Important Announcement!", $TestMessage());

The second method of streaming a function call is by including the stream keyword in the function definition itself. This will cause all output generated by the function to be sent back as the default return value, which can be overrided through use of the return statement (in which case the stream output is lost).

Here is another example of how to use function streaming to make your code simpler and easier to read. The authorizeClient() function only accepts a string as the "access denied" page text, forcing you to use it like this:

if (uppercase(username) != "FRED" && uppercase(password) != "DERF") then
  authorizeClient("Fred's Realm", "<!-- lots of HTML goes here -->");
end if;

Obviously, this can get ugly real quick if you want to return a nicely formatted "access denied" page that is more sophisticated than a basic HTML page. We can use a stream function to make this much easier, like so:

if (uppercase(username) != "FRED" && uppercase(password) != "DERF") then
  authorizeClient("Fred's Realm", AccessDeniedPage());
    
  stream function AccessDeniedPage
    <<
    <center><b>Ha Ha!</b></center>
    <!-- lots of HTML goes here -->
    >>
  end function;
end if;
Function Libraries

In the example above,the user-defined functions MySiteHeader() and MySiteFooter() were defined to be able to insert a standard site header and footer in any HTML document. As noted, you could put the function directly in your template or use the include statement to include a separate script which contains the functions. Alternately you could create a function library or script library for those functions and save yourself a little bit of trouble.

Function Libraries are either compiled code libraries (as developed with the WebSiphon SDK) or script libraries which contain user-defined functions. Function libraries are placed in the Libraries folder inside WebSiphon Data folder and thereby become part of the WebSiphon environment. Any functions from a function/script library are available to any script/template that WebSiphon executes. Essentially, library functions become new built-in functions.

This is a powerful tool because it enables the creation of modular code and the ability to reuse your functions across multiple templates.

Note: With script libraries, the contents of all script libraries are automatically included with every template as they are compiled. Therefore, if you put simple text or HTML in a script library (but not inside a function), it would autmatically be inserted at the top of every page served through WebSiphon. Since functions become part of the compliled SiphonScript code, they are not be visible in the HTML output unless specifically called. However, since script library functions become part of the compiled code and all script libraries are compiled into every template, you may notice an increase in the filesizes of your template files as you add more script libraries or script library functions. In practice, this does not present a major issue because the compiled code stored in each template's resource fork is fairly compact.

As an example we'll use the MyPageHeader() and MyPageFooter() functions from above.

Example Script Library:

<<
  // My company's standard site header
  function MyPageHeader(page_title)
    <<
    <HTML>
    <HEAD>
    <TITLE>{page_title}</TITLE>
    </HEAD>
    <BODY>
    <H1>{page_title}</H1>
    <HR>
    >>
  end function;

  // My company's standard site footer
  function MyPageFooter
    <<
    <HR>Copyright (c) 1998 My Company</BODY></HTML>
    >>
  end function;
>>

This content would then be saved to a file called "MyCompany.lib" (the actual name of the library file is irrelevant) and moved to the "(script)" folder inside the WebSiphon Data:Libraries: folder. After restarting WebSiphon (or the webserver the case of the WebSiphon Plug-in) the functions would be available to any template. Then we could create a new template utilizing these functions.

Example Template:

<<
page_title = "Company Information";
>>

{MyPageHeader(page_title)}

    <p>Company information here</p>

{MyPageFooter()}

Resulting HTML:

    <HTML>
    <HEAD>
    <TITLE>Company Information</TITLE>
    </HEAD>
    <BODY>
    <H1>Company Information</H1>
    <HR>

    <p>Company information here</p>

    <HR>Copyright (c) 1998 My Company</BODY></HTML>

contents prev next

Copyright (c)1996-2003 Purity Software