[ Previous ] [ Contents ] [ Index ] [ Next ]

Tcl Interface Tutorial

Example 1: "Hello World"

This simple example can be accomplished in either of the two methods of Tcl script development described above. Since the actual "work" of the script is accomplished by only one Tcl command (ns_return), it's easier to use the method where you just type the command into a .tcl file in your pages directory. That method is illustrated first. However, the alternative method is also described for the sake of illustrating how to create a Tcl procedure and bind it to an URL.


"Hello World" as a file in the pages directory:
This example details how to write a WWW "Hello World" operation in Tcl and store it in a .tcl file in the pages directory.

  1. Create a new text file with an editor in the pages directory for the virtual server you want to run the script on. The pages directory for a virtual server is defined by the PageRoot parameter in the configuration file. By default, the pages directory is in the /servers/server-name/pages directory under the AOLserver home directory. Name the file hello.tcl. (The file must have .tcl as the extension.)

  2. Enter the following Tcl command into the hello.tcl file:

        ns_return $conn 200 text/plain "Hello World"
    

The ns_return command takes as arguments: the passed in connection ($conn), an HTTP return status (in this case, 200 for success), a MIME type (text/plain), and the actual string to return ("Hello World").

  1. In any browser, open the URL http://www.yourorg.com/hello.tcl to see the "Hello World" message.


"Hello World" as a procedure bound to an URL:
This example details how to write a WWW "Hello World" operation in Tcl and bind it as a procedure to a URL.

  1. From a Page window in AOLpress choose menu item Tools Administer Server... Choose your server from the dialog that appears. If it is not listed, type in http:// followed by the name of the host where the server is running. A page containing links to several server functions appears. If you're using another browser, go to the /NS/Admin page on your server.

  2. Scroll down to the section labeled Tcl Scripting and follow the link to View/Edit Script Files.

  3. The AOLserver returns a page with a list of existing Tcl scripts and directories of Tcl scripts to view and/or modify. Scroll to the end of the page and enter hello.test in the entry box labeled Create a new script in this directory called.

  4. Press the Create... button. The AOLserver returns a page with a large text area form where you can enter the text of the hello world operation.

  5. Enter the following text of the script below. (Lines beginning with a # sign are comments and may safely be skipped). This example is also available in the /examples/tcl/hello.tcl file.

        
    

    # Example 1: Hello World
    #
    # This simple operation just returns a plain text message.
    
    # Things to notice:
    #
    # * ns_register_proc takes as arguments:
    # *   the HTTP method
    # *   the URL that the procedure handles
    # *   the procedure that is executed
    #
    # * ns_return takes as arguments:
    # *   the passed in connection
    # *   a return status, in this case 200 for success,
    # *   a MIME type
    # *   the actual string to return
    #
    # * ns_return properly formats the HTTP response for you.
    
    ns_register_proc GET /example/hello hello
    
    proc hello {conn context} {
    	  ns_return $conn 200 text/plain "Hello World"
    }

  1. Press the Create Script button.

    The AOLserver:

  2. Because the AOLserver is a dynamic extensible environment, the /example/hello URL is immediately registered to be handled by the hello procedure. To test your new operation, open the /example/hello URL in any browser to receive the "Hello World" message.

Example 2: End-to-End Tcl Extension

The following is a more extensive example typical of an end-to-end AOLserver Tcl extension. In this case, one operation dynamically generates and returns a page to the user. The page includes a form where the user enters a few values. When the submit button is pressed, another operation extracts the data entered by the user and generates a short story that is returned to the user.


Extract HTML form post data from the Ns_Set in Tcl:
  1. From a Page window in AOLpress choose menu item Tools Administer Server... Choose your server from the dialog that appears. If it is not listed, type in http:// followed by the name of the host where the server is running. A page containing links to several server functions appears. If you're using another browser, go to the /NS/Admin page on your server.

  2. Scroll down to the section labeled Tcl Scripting and follow the link to View/Edit Script Files.

  3. The AOLserver returns a page with a list of existing Tcl scripts and directories to view and/or modify. Scroll to the end of the page and enter story.test in the entry box labeled Create a new script called.

  4. Press the Create... button. The AOLserver returns a page with a large text area form where you can enter the text of the script.

  5. Enter the following text of the script below (lines beginning with a # sign are comments and may safely be skipped):

    # Example 3: Form generation and handling
    #
    # Two functions are registered. One generates and
    # returns an HTML form, and the other processes
    # the data in the form.
    #
    # Things to notice:
    #
    # * Different functions are registered to the same
    # URL with different methods.  Note that some browsers
    # do not cache results properly when you do this.
    #
    # * The genstory function returns an error status
    # (500) if the client doesn't pass in any form data.
    #
    # * Form data is stored in an ns_set, and accessed
    # like any other set (e.g., headers)
    #
    # * A counter is used to loop through all the key
    # value pairs in the form.
    
    ns_register_proc GET /example/genstory genstoryform
    ns_register_proc POST /example/genstory genstory
    
    proc genstoryform {conn context} {
    	  ns_return $conn 200 text/html \
    "<HTML>
    <HEAD>
    <TITLE>Automatic Story Generator</TITLE>
    </HEAD>
    <BODY>
    <H1>
    Automatic Story Generator
    </H1>
    <FORM ACTION=http:/example/genstory
    METHOD=POST>
    Noun: <INPUT TYPE=text NAME=noun1><BR>
    Noun: <INPUT TYPE=text NAME=noun2><BR>
    Name: <INPUT TYPE=text NAME=name1><BR>
    Name: <INPUT TYPE=text NAME=name2><BR>
    Adjective: <INPUT TYPE=text NAME=adjective1><BR>
    Adjective: <INPUT TYPE=text NAME=adjective2><BR>
    Verb: <INPUT TYPE=text NAME=verb1><BR>
    Verb: <INPUT TYPE=text NAME=verb2><BR>
    <P><INPUT TYPE=submit VALUE=\"Generate\">
    </FORM>
    <P>
    </BODY></HTML>
    "}
    
    proc genstory {conn ignore} {
    
    	  set formdata [ns_conn form $conn]
    
    	  if {$formdata == ""} {
    		  ns_return $conn 200 text/plain "Need form data!"
    		  return
    	}
    
    	# Build up a human-readable representation of the form data.
    
    	  set hrformdata "<dl>"
    	  set size [ns_set size $formdata]
    	  for {set i 0} {$i < $size} {incr i} {
    		  append hrformdata "<dt>[ns_set key $formdata $i]</dt>\
    			<dd>[ns_set value $formdata $i]</dd>"
    	  }
    	  append hrformdata "</dl>"
    
    	  ns_return $conn 200 text/html \
    "<HTML>
    <HEAD>
    <TITLE>The story of [ns_set get $formdata name1] and
    [ns_set get $formdata name2]</TITLE>
    </HEAD>
    <BODY>
    <H1>
    The story of [ns_set get $formdata name1] and
    [ns_set get $formdata name2]
    </H1>
    <P>Once upon a time [ns_set get $formdata name1] and
    [ns_set get $formdata name2] went for a
    walk in the woods looking for a [ns_set get $formdata noun1].
    [ns_set get $formdata name1] was
    feeling [ns_set get $formdata adjective1] because
    [ns_set get $formdata name2] was so
    [ns_set get $formdata adjective2]. So
    [ns_set get $formdata name1] decided to
    [ns_set get $formdata verb1] [ns_set get $formdata name2]
    with a [ns_set get $formdata noun2]. This made
    [ns_set get $formdata name2] [ns_set get $formdata verb2].
    <P><CENTER>The End</CENTER>
    The form data that made this possible:<BR>
    $hrformdata
    </BODY></HTML>"
    }
    

  1. Press the Create Tcl Script button.

    The AOLserver:

Because the AOLserver is a dynamic extensible environment, the /example/genstory URL is immediately ready. To test the new operations, open the /example/genstory URL in any browser to receive a page for entering the information needed to create the story. When you press the Generate button, your browser POSTs to the same /example/genstory URL. Because you must register both the method and URL, the AOLserver can distinguish the POST from a GET and can invoke the correct procedure to generate your story.

Example 3: Returning Content to Client

In most cases, a Tcl operation simply returns either a string or file to the client, and for these cases, the ns_return command can be used as shown in the examples above. The ns_return command generates a properly formatted HTTP response, including headers.

The ns_respond command is more powerful. In some cases, you may need to write a string directly using the low-level function ns_write command. The example below shows three ways to return an HTTP redirect to the client.


Use the low-level ns_write command:
  1. From a Page window in AOLpress choose menu item Tools Administer Server... Choose your server from the dialog that appears. If it is not listed, type in http:// followed by the name of the host where the server is running. A page containing links to several server functions appears. If you're using another browser, go to the /NS/Admin page on your server.

  2. Scroll down to the section labeled Tcl Scripting and follow the link to View/Edit Script Files.

  3. The AOLserver returns a page with a list of existing Tcl scripts to view and/or modify. Scroll to the end of the page and enter write.test in the entry box labeled Create a new script called.

  4. Press the Create... button. The AOLserver returns a page with a large text area form where you can enter the text of the script.

  5. Enter the following text of the script below (lines beginning with a # sign are comments and may safely be skipped):

    # Example 4: Implementing redirects with ns_respond and
    # ns_write
    #
    # /example/not_here uses ns_respond to return an HTTP 
    # redirect to /example/finaldest.
    # /example/not_here2 does the same thing using ns_write
    # /example/not_here3 does the same thing with
    # ns_returnredirect
    #
    # Things to notice:
    #
    # * When you use ns_write, you need to compose the
    # entire response;
    #
    # * "ns_info location" returns the http://hostname
    # part of the URL that you can use to generate
    # fully qualified URLs.
    #
    # * ns_returnredirect is a lot simpler than either
    # ns_respond or ns_write
    
    ns_register_proc GET /example/finaldest finaldest
    ns_register_proc GET /example/not_here not_here
    ns_register_proc GET /example/not_here2 not_here2
    ns_register_proc GET /example/not_here3 not_here3
    
    proc not_here {conn ignore} {
    	set headers [ns_set new myheaders]
    	ns_set put $headers Location 
      [ns_info location]/example/finaldest
    	ns_respond $conn -status 302 -type text/plain \
    		-string "Redirection" -headers $headers
    }
    
    proc not_here2 {conn context} {
    	ns_write $conn \
    "HTTP/1.0 302 Document follows
    MIME-Version: 1.0
    Content-Type: text/html
    Content-Length: 291
    Location: [ns_info location]/example/finaldest
    
    <HTML><HEAD><TITLE>Redirection</TITLE></HEAD><BODY>
    <H1>Redirection</H1>The actual location of what
    you were looking for is
    <A HREF=\"[ns_info location]/example/finaldest\">
    here.</A>
    </BODY></HTML>"
    }
    
    proc finaldest {conn context} {
    	ns_return $conn 200 text/plain \
    		"You have arrived at the final destination"
    }
    
    proc not_here3 {conn context} {
    	ns_returnredirect $conn \
    		[ns_info location]/example/finaldest
    }

  1. Press the Create Tcl Script button.

    The AOLserver:

Because the AOLserver is a dynamic extensible environment, the /example/not_here, /example/not_here2, and /example/not_here3 URLs are immediately ready. To test the new operations, open the /example/not_here or /example/not_here2 or /example/not_here3 URLs in any browser. Your browser will be redirected to the /example/finaldest URL, which returns a simple message. The ns_respond command in not_here and the ns_returnredirect command in not_here3 encapsulate all the low level writes required in not_here2.

Example 4: Interacting with the Database

One of the strengths of the Tcl API is its ability to query and modify databases quickly and easily. It will tell you the structure of the database as well as let you query and modify its contents.

On a database error, these commands generate Tcl errors, so you may need to use the Tcl catch command to handle database errors that are generated by user input.


Use ns_table and ns_column commands to describe a database table:
  1. From a Page window in AOLpress choose menu item Tools Administer Server... Choose your server from the dialog that appears. If it is not listed, type in http:// followed by the name of the host where the server is running. A page containing links to several server functions appears.

  2. Scroll down to the section labeled Tcl Scripting and follow the link to View/Edit Script Files.

  3. The AOLserver return a page with a list of existing Tcl scripts to view or modify. Scroll to the end of the page, and enter table.test in the entry box labeled Create a new script called.

  4. Press the Create... button. The AOLserver returns a page with a large text area form where you can enter the text of the script.

  5. Enter the following text of the script below (lines beginning with a # sign are comments and may safely be skipped):

    # Example 5: Describing a database table
    #
    # /example/describetable prints out a column-by-column
    # description of the database table. The database pool name and
    # table name are specified at the end of the URL -- e.g.,
    # /example/describetable/nsdbpool/ns_users
    #
    # Things to notice:
    #
    # * ns_returnbadrequest returns a nicely formatted message
    #   telling the client they submitted an invalid request.
    #
    # * "ns_conn urlv" returns a Tcl array whose elements are the
    # slash-delimited parts of the URL.
    #
    # * The describetable function loops through all the columns
    # and uses "ns_column valuebyindex" to get the type of each
    # one.
    #
    # * ns_returnnotice nicely formats the return value.
    
    ns_register_proc GET /example/describetable describetable
    proc describetable {conn ignore} {
        if {[ns_conn urlc $conn] != 4} {
    	return [ns_returnbadrequest $conn \
    		"Missing table name and or poolname"]
        }
        set pool [lindex [ns_conn urlv $conn] 2]
        if {[lsearch $pool [ns_db pools]] == -1} {
    	return [ns_returnbadrequest $conn \
    		"Pool $pool does not exist"]
        }
    	
        set db [ns_db gethandle $pool]
        set table [lindex [ns_conn urlv $conn] 3]
        set tinfo [ns_table info $db $table]
        if {$tinfo == ""} {
    	return [ns_returnbadrequest $conn \
    		"Table $table does not exist"]
        }
        set output "Description of table:\
    	 <blockquote><tt>$table</b></tt></blockquote><dl>"
        set size [ns_column count $tinfo]
        for {set i 0} {$i < $size} {incr i} {
    	append output "<dt>[ns_column name $tinfo $i]\
    		<dd>[ns_column typebyindex $tinfo $i]</dd>"
        }
        append output "<hr>"
    ns_returnnotice $conn 200 "Table: $table in pool $pool" $output
    }

  1. Press the Create Tcl Script button.

    The AOLserver:

Because the AOLserver is a dynamic extensible environment, the /example/describetable URL is immediately ready. To test the new operations, open the /example/describetable/<poolname>/<tablename> URL in any browser, where you substitute <poolname> with the name of a database pool and <tablename> with the name of a table in the database. The AOLserver returns a page that describes the schema of the selected table.


Query the database with ns_db:
  1. From a Page window in AOLpress choose menu item Tools Administer Server... Choose your server from the dialog that appears. If it is not listed, type in http:// followed by the name of the host where the server is running. A page containing links to several server functions appears. If you're using another browser, go to the /NS/Admin page on your server.

  2. Scroll down to the section labeled Tcl Scripting and follow the link to View/Edit Script Files.

  3. The AOLserver returns a page with a list of existing Tcl scripts to view or modify. Scroll to the end of the page and enter query.test in the entry box labeled Create a new script called.

  4. Press the Create... button. The AOLserver returns a page with a large text area form where you can enter the text of the script.

  5. Enter the following text of the script below (lines beginning with a # sign are comments and may safely be skipped):

    # Example 6: Getting data from the database
    #
    # /example/getemps queries a database in the default
    # pool and returns a list of all the employees listed 
    # in the employees table.  It assumes a table called
    # employees exists with the column emp_name.
    
    #
    # Things to notice:
    #
    # * Use "ns_dbgethandle" to get a handle for the database.
    #   It assumes that there is a database pool named "default".
    #
    # * Use "ns_db select" to query the database and
    # "ns_db getrow" to retrieve data.
    #
    # * Rows are returned as ns_sets.
    #
    
    ns_register_proc GET /example/getemps getemps
    
    proc getemps {conn context} {
    
    	set ul "<UL>"
    	set db [ns_db gethandle default]
    	set row [ns_db select $db \
    	"select emp_name from employees order by emp_name;"]
    	while {[ns_db getrow $db $row]} {
    	 append ul "<LI>[ns_set get $row emp_name]\n"
    	}
    	append ul "</UL>"
    	ns_returnnotice $conn 200 "Employee list" $ul
    }

  1. Press the Create Tcl Script button.

    The AOLserver:

Because the AOLserver is a dynamic extensible environment, the /example/getemps URL is immediately ready. To test the new operation, open the /example/getemps URL in any browser. The AOLserver returns a list of the names in the employee table.

Top of Page

[ Previous ] [ Contents ] [ Index ] [ Next ]
Copyright © 1996 America Online, Inc.