[SparForte][Banner]
[Top Main Menu] Intro | Tutorials | Reference | Packages | Examples | Contributors   [Back Page]      [Next Page]  

Template Tutorial 1: Basic Templates

Some programming languages designed for web development can be embedded into an HTML template to generate a dynamic web page. SparForte scripts can also be embedded into HTML templates in this way, or can be embedded in templates for several other types of documents.

Running SparForte From a Web Server

SparForte can be run from a web server using CGI (Common Gateway Interface). The exact configuration depends on your operating system and your web server.

As an example, with Apache, you can create scripts with a .cgi ending in a cgi-bin directory. The specify the location of the SparForte interpreter in the "#!" line at the top of script.

CGI scripts can work with or without templates.

Using SparForte with CGI

The SparForte cgi package contains the basic functionality for writing CGI scripts. This is included by default. If you prefer, support for the gnat.cgi can be added when SparForte is built, though this disables certain features. See the gnat.cgi package reference for more information.

-- Display a web page with "Hello World"

cgi.put_cgi_header;
cgi.put_html_head( "test", "" );

? cgi.html_encode( "Hello World" ) @ "</body>" @ "</html>";
 

Example: Display all pre-defined variables

This draws a web page similar to this:


Hello World

The following is a very simple CGI script using the cgi package. It shows the values submitted through a HTML form.

procedure minimal_cgi is
-- Demonstrate SparForte's CGI interface
-- based on AdaCGI's minimal.adb example
 
-- To run this script directly (without a HTTP server), set the
-- environment variable REQUEST_METHOD to "GET" and the variable
-- QUERY_STRING to either "" or "x=a&y=b".
 
begin
  cgi.put_cgi_header;
  cgi.put_html_head( "Minimal Form Demonstration" );
  if cgi.input_received then
    cgi.put_variables;
  else
    put_line( "<form method=" & ASCII.Quotation & "POST" & ASCII.Quotation &
    ">What's your name?<input name=" & ASCII.Quotation & "username" &
    ASCII.Quotation & "><input type=" & ASCII.Quotation & "submit" &
    ASCII.Quotation & ">" );
  end if;
  cgi.put_html_tail;
end minimal_cgi;
 

Example: A Simple CGI Script

Any errors reported by SparForte will be written to the web server's error log.

Using SparForte with Web Templates

SparForte can also run as a template engine like PHP. Although it doesn't yet have an Apache module, you can use the CGI mechanism to use templates. First, the CGI script can do any necessary computation. Then, using a directive called called pragma template, a web template is loaded containing HTML and embedded SparForte statements.

The template pragma has two parameters: the type of template and an optional path to the template. If you don't include a path to the template, SparForte will assume that the template has the same name as your script but with a ".tmpl" file name extension. Use a template type of html to return a web page.

Use the main script to run operating system command, database queries or complex calculations. Once SparForte has executed this script, SparForte try will load a template called "status.tmpl".

What's in a Template File?

A template file should contain the web page SparForte will display. Embed SparForte scripts within the template using <?spar tag. The output from the scripts is written directly into the web page. For example, to insert the values of SparForte variables in a web page, use the question mark command.

<!-- status.tmpl: template for the status.sp script -->
<html>
<head>
<title>Users on the System</title>
</head>
<body>
<h3>Users on the System<h3>
<p>There are <?spar ?user_count; ?> users on the system.</p>
</body>
</html>
 

Example: A Simple Web Template (For the Simple Template Script)

This would result in a web page similar to


Users on the System

There are 4 users on the system.

The <?spar...?> tag can contain any kind of SparForte script and can be longer than one line.

The scripts in the template are after the main script. For security, scripts run in a restricted shell and are not able to run external operating system commands. (You can disable this protection with pragma unrestricted_template but anyone who can edit the template will be able to run commands with the authority of the web server.

Here is a longer example:

CGI Script (test.cgi) Template (test.tmpl)
#!/usr/local/bin/spar
pragma unrestricted_template( html );
<html>
<head>
<titleSparForte Rocks!</title>
</head>
<body>
<h2>SparForte Rocks!</h2>
<h3>System Info</h3>
<table border=1 summary="System Info">
<tr>
<td align="right"><b>System Name:</b></td>
<td><?spar uname -n; ?></td>
</tr>
<tr>
<td align="right"><b>Uptime:</b></td>
<td<pre><?spar uptime; ?></pre></td>
</tr>
<tr>
<td align="right"><b>Database Tables:</b></td>
<td><pre><?spar
db.connect( "ken" );
if not db.is_connected then
put_line( "<i>Unable to connect to database</i>" );
end if;
db.list; -- show a list of database tables
?></pre></td>
</body>
</html>
Results in a Web Browser (Taken from BUSH 1.0)
[Screenshot]

If an error occurs, it will be written to the web server error log. In most cases, it will also be written to the web page. If you think an error occurred but don't see it on the web page, check the error log.

On the web page, errors will appear something like this:

i

SparForte says

/srv/www/cgi-bin/t_tmpl.sp: 13: 10: in script
 i1 := j1;
         ^ type i is not compatible with type j


Securing Your Web Site

Security is one of the biggest challenges for a website. You should never work with data that comes from outside of your website unless it has been sanitized and validated, nor should you display any data on the web page or put any data in a URL that is not escaped for special characters.

If you fail to protect your program, you will be vulnerable to Internet attacks such as injections (when strings variables are copied into SQL queries or OS commands) or cross-site scripts (where strings of HTML or JavaScript are pasted back into a web page to take over a user session or deface a web site).

If possible, try to run a script in restricted shell mode. This will prevent most exploits. However, if a restricted shell is too restrictive, remember to do the following things:

  • Use cgi.url_encode for all URL's being returned.
  • Use cgi.html_encode for all string values that will used to build web content.
  • Use the strings validation functions like strings.is_alphanumeric on all strings.
  • Sanitize input values with strings.fix or strings.trim where appropriate.
  • Convert or cast input values from strings to their appropriate type using functions like numerics.value.

SparForte's strong typing is very good at keeping data separate that should remain separate. It can help protect your site from putting unencoded data on a web site. For example, create new string types like "unescaped_string" and "escaped_string".

The create your own version of the html_encode and url_encode functions that have an unescaped_string parameter and returns a escaped_string. Create your own version of put or put_line that use escaped_string parameters.

type unescaped_string is new string;
type escaped_string is new string;

function html_encode( s : unescaped_string ) return escaped_string is
begin
  return cgi.html_encode( s );
end html_encode;

function url_encode( s : unescaped_string ) return escaped_string is
begin
  return cgi.url_encode( s );
end url_encode;

procedure put_html( s : escaped_string ) is
begin
  put( s );
end put_html;

procedure put_line_html( s : escaped_string ) is
begin
  put_line( s );
end put_line_html;
 

Example: Using Strong Typing to Ensure Web Page Content is Encoded

Now SparForte's type system can check that only encoded strings are used when outputting web page content. You could, of course, use different types for HTML and URL strings as well to prevent them from being mixed.

Study Questions

  1. Why is it important to check input submitted to a web application, especially one that can run shell shell commands and database queries?
  2. Why are templates normally run in restricted shell mode?
 
[Right Submenu]

 Command Prompt Tutorial 1: SparForte as a Calculator

 Command Prompt Tutorial 2: Basic Shell Commands

 Command Prompt Tutorial 3: Working with Databases

 Script Tutorial 1: Basic Commands Scripts

 Script Tutorial 2: Intermediate Program Scripts

 Script Tutorial 3: Data Types

 Template Tutorial 1: Basic Templates

 Template Tutorial 2: Intermediate Templates

 GCC Tutorial: Compiling SparForte Scripts

 Debugging Tutorial - Using the SparForte Debugger

 Creating a Profile Script

 Calling SparForte from C: A Tutorial

 SparForte For PHP Developers

 SparForte Best Practices

[Back to Top] Back To Top [Small Forte Symbol]