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

Template Tutorial 2: Intermediate Templates

Some web experts recommend using a MVC (model, view, controller) layout for web templates. What they mean by that is that the business logic (or page routing, depending on the expert), the formatting of the web page, and the content should be separated. In large organizations, the programmer will to the calculations, the web designer will create the look of the web page and an editor will fill in text. By separating these tasks, each person can work on his/her part of the web site without interfering with the others.

The other advantage of MVC is that it separates the appearance of the page from the data, making it easier to "skin" a site for different clients without altering the underlying program.

As shown in Tutorial 1, SparForte templates consist of a CGI script plus an HTML template. By default, both files are located in the same directory. The template file can be located in a different directory. pragma template can have the location of the template file as a second parameter. For example, if you have a web designer and programmer, place the templates in a different directory with different access rights so that these two people will not interfere with each other.

HTML Form Variables

There are several ways to share information between templates. Data can be stored in cookies, in files, in database tables or it can be shared using HTML variables. HTML variables are created by using <input> tags inside of forms.

There are two ways to read HTML variables in SparForte. The first method is to import the variable. In the same way as you import shell environment variables, pragma import can import HTML variables by using "cgi" instead of "shell".

first_name : string;
pragma import( cgi, first_name );
 

Example: How to Import HTML Form Variables

The second method is to use the builtin cgi package. cgi.value will retrieve the value of a HTML variable in a form. The value function requires the name the variable, the instance (because there may be multiple variables with the same name), and whether or not to raise an exception if the variable is not there.

first_name : string := cgi.value( "first_name", 1, false );
 

Example: How to Read HTML Form Variables with the cgi Package

The import method provides greater reliability: the name of the SparForte variable must be the same as the HTML variable, and if the import fails, the template will stop before it can execute the main script. The CGI method can load HTML variables on demand to improve performance, and is compatible with GCC.

cgi.input_received is true if form data was received. You can use this function to check for form data before trying to read the values.

Web Server Variables

You can also use pragma import to get environment information from the web server using "shell" import type. The variables available depends on the web server you are using. Common variables include:

  • DOCUMENT_ROOT - the top-most directory containing the web site
  • HTP_REFERER - the page that contained the form being submitted
  • HTTP_USER_AGENT - the user's web browser
  • PATH_INFO - extra characters after the URL
  • QUERY_STRING - the web variables in encoded form
  • REMOTE_ADDR - the user's IP number
  • REMOTE_HOST - the hostname for REMOTE_ADDR
  • SERVER_NAME - the name of the server the web page is on

HTTP_USER_AGENT : string;
pragma import( shell, HTTP_USER_AGENT );
-- Get the name of the user's web browser
-- e.g. Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.3) Gecko/20040922
 

Example: How to Standard Web Server Variables

A Guestbook Web App

Here is a larger example of a simple guestbook where people can leave their names and a message.

#!/usr/local/bin/spar
 
-----------------------------------------------------------------------------
-- GUESTBOOK.CGI
--
-- This is a simple guest book written in SparForte.
-- Before using this guestbook, create a "guestbook" table with "name" and
-- "message" fields. Make sure that the web server has permission to insert
-- and select on the table.
-----------------------------------------------------------------------------
 
 
pragma template( html );
-- this is a web template
 
pragma debug;
-- show SparForte errors on web page, enable assert/debug pragmas. Comment this
-- out to record errors only in the web server log.
 
pragma restriction( no_external_commands );
-- this template is self-contained
 
-----------------------------------------------------------------------------
-- USER CONFIGURATION AREA
-----------------------------------------------------------------------------
 
dbname : constant string := "ken";
-- the name of the database
 
dbtable : constant string := "guestbook";
-- the name of the guestbook table
 
guestbook_title : constant string := "Our Guestbook";
-- the title of the guestbook
 
allowed_host_address : constant string := "127.0.0.1";
-- the host computer with the CGI script that is allowed to submit things to
-- the guestbook (a security check)
 
-----------------------------------------------------------------------------
-- GLOBAL VARIABLES
-----------------------------------------------------------------------------
 
REMOTE_ADDR : constant string := "";
 
pragma import( shell, REMOTE_ADDR );
-- Apache variable for address of requesting machine
 
ok_to_post : boolean;
-- true if this is the correct host for posting
 
-----------------------------------------------------------------------------
-- MAIN
-----------------------------------------------------------------------------
 
db.connect( dbname ); -- open a connection to the database
ok_to_post := REMOTE_ADDR = allowed_host_address; -- is this host OK?
 
-- VIM vi editor will show correct hilighting with this:
-- vim: ts=8 sw=4 tw=72 fdm=indent ft=ada smarttab noexpandtab
 

Example: Guest Book Example (guestbook.cgi, CGI Portion)

<html>
<head>
 
<title<?spar ? guestbook_title; ?></title>
</head>
<body>
<h2><?spar ? guestbook_title; ?></h2>
<form action="/cgi-bin/guestbook.cgi" method="post">
<p>Please sign our guestbook.</p>
 
<table border="1" cellspacing="2" cellpadding="1" summary="your message">
<tr>
<td bgcolor="lightgrey">Your Name:</td>
<td><input type="input" name="name" size="40"></td>
</tr>
<tr>
<td bgcolor="lightgrey">Your Message:</td>
 
<td><input type="input" name="message" size="80"></td>
</tr>
</table>
 <br>
<input type="submit" name="Submit" value="Sign">
</form>
<hr />
<h3>Messages from our Guests</h3>
 
<table border="1" cellspacing="2" cellpadding="1" width="98%" summary="other messages">
 
<?spar
  -- if there is a new guestbook entry, insert
  if cgi.input_received then
    if ok_to_post then
      if cgi.key_exists( "name", 1 ) then
        declare
          name : string := cgi.value( "name", 1, false );
          message : string := cgi.value( "message", 1, false );
        begin
          ? name;
          ? message;
          db.prepare( "insert into " & dbtable & " values ('" &
            name & "','" & message & "')" );
          db.execute;
        end;
      else
        put_line( "<b>This remote host is not allowed to post to the guestbook</b>" );
      end if;
    end if;
  end if;
 
  -- show the messages
  db.prepare( "select name, message from " & dbtable );
  db.execute;
  if db.tuples = 0 then
    put_line( "<tr>" );
    put_line( "<td><i>You are the first person to sign the guestbook.</i></td>" );
    put_line( "</tr>" );
  else
    put_line( "<tr>" );
    put_line( "<td bgcolor=lightgrey><b>Name</b></td>" );
    put_line( "<td bgcolor=lightgrey><b>Message</b></td>" );
    put_line( "</tr>" );
    while not db.end_of_query loop
      db.fetch;
      put_line( "<tr>" );
      put_line( "<td>" & db.value( 1 ) & "</td>" );
      put_line( "<td>" & db.value( 2 ) & "</td>" );
      put_line( "</tr>" );
    end loop;
  end if;
  db.clear;
?>
 
</table>
</body>
</html>
 

Example: Guest Book Example (guestbook.tmpl, Template Portion)

Conditional Output

The ability to chose between pieces of HTML code is a powerful feature of web template processors, including SparForte. Since SparForte uses embedded shell scripts, it uses the status code returned from the scripts to control whether the pieces of the template are included or not. If an embedded script returns a status code of zero (success), the HTML following the script will be included in the final web page.

Study Questions

  1. Is MVC the only model for designing web applications?
  2. Can "pragma import" import to a constant?
  3. What are the limitations of getting HTML variables using "pragma import"?
 
[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]