Purpose: describe for the gentle reader how one can do simple [CGI] applications with nothing up our sleeves... ---- First, here's a sample CGI script: ---- #! /usr/tcl84/bin/tclsh proc generate_page {} { puts stdout "Content-type: text/html\n" puts stdout "" puts stdout "" puts stdout "Wave to the world!" puts stdout "" puts stdout "" puts stdout "Hello, world!" puts stdout "" } if {[catch { generate_page } err]} { puts stdout "Content-type: text/plain\n\n$err" } ---- Some key concepts: * The first line tells the web server what program to run to execute the script. Change this line to be the location of the tclsh executable on your system. * Your program should output a line containing the content type of the page. In the example, it's an HTML file. * The Content-type line MUST be followed by a blank line, otherwise you'll get an error message. Note that [puts], by default, adds its own newline. The temptation is to specify two, but one is correct. * The remainder of the script outputs a web page (in this example). ---- Now, what do you do with it? That's a bit tougher to answer. See, it all depends on how the http server was configured. The best thing to do is to contact the person who knows about the specific web server and ask. ''"But"'', you ask, ''"what if '''I''' am the person who installed the server, and I have no idea what the server is expecting?"'' Well, all I can do is suggest that you find a newsgroup, mailing list, or web forum that supports the server in question, and ask the kind people there what the default directories, naming conventions, etc. are. A good place to start is http://www.equi4.com/259 . ---- The "#! /usr/tcl84/bin/tclsh" is more specific to Apache type of servers. Windows IIS 4.x and later does NOT use this, it uses a script map to control execution based on file extension names (e.g., *.cgi, *.cgt, *.tcl) ''Yes - This is true - But the "#! /usr/tcl84/bin/tclsh" does not hurt the application - as it is seen as a comment by the Tcl Intrepreter when you execute it via IIS. We use both web environments systems here, the same code runs on Apache and IIS. But I do see you point that is can be dropped. ([DB])'' You might also want to consider using [Don Libes] [cgi.tcl] also - it can be very handy for, HTML Generation, forms and form manipulations. Additionally, I would recommend [TimpleSQL] if you want to CGI content into a database. ---- To do anything interesting with CGI's, though, you need to be able to *receive* data as well as send it, and that's where [ncgi], [cgi.tcl] and company come in. [CL] finds it not-hard to receive CGI data "by hand", wonders why all the "puts stdout ..." above, rather than just "puts ..." ---- I also wonder why the example uses all those "puts stdout ..." rather than just "puts". And I wonder how I can print the output of a command instead of "Hello, world!". I tried and the output is printed OK, but nothing else afterwards. Say, "" don't get printed. I am not sure what you mean for ''the output of a command''... I changed the above proc to display local time. #! /usr/tcl84/bin/tclsh proc generate_page {} { puts stdout "Content-type: text/html\n" puts stdout "" puts stdout "" puts stdout "Local time" puts stdout "" puts stdout "" puts stdout "Local time is [clock format [clock seconds]]." puts stdout "" } if {[catch { generate_page } err]} { puts stdout "Content-type: text/plain\n\n$err" } ---- I run: puts "a [parray env] b" I expect... "a (a long list of vars) b" ...but I get: "(a long list of vars) a b" Why? Of course, this works: puts "a" parray env puts "b" But if I can't intersperse commands with the text and have to use [puts] for every single line individually, CGI with vanilla Tcl becomes a major pain. Look at the '''generate_page''' example. How '''readable''' is that? ---- parray was a bad choice since it prints on stdout AND returns an empty string :-) try [[array get env]]. And you can write generate_page as proc generate_page {} { puts stdout "Content-type: text/html Local time

Local time is [clock format [clock seconds]].

" } ---- Still tough. [[[array get] env]] does not produce the same formatted output as [[[parray] env]]. In order to reproduce [parray]'s behavior, I would have to [foreach] on [[[array get] ::env]] and everything becomes very very tricky. Assigning variables produces noise and breaks the script. Wrapping it in a proc that does not [return] anything produces "empty string" and breaks the script. Wrapping it in a proc that returns something works, but rules out many usual/obvious solutions and require a lot more planning and thinking than it would in a regular shell or Tk/GUI script. My conclusion, so far, is that using Tcl for [CGI] is a bad idea. In most languages, especially those better suited to [CGI], like [Perl] and [PHP] or even [Bash], commands do not return or output anything until you "print" or "echo" something explicitly. Since Tcl's commands and [[anything in square brackets]] always return something, at least an empty string, writing [CGI] with Tcl becomes such a mine field. Lots of simple lines I have been writing routinely for so long now explode under my feet. Tcl no longer is the nice, laid-back language it used to be. Of course it is possible, but not the best tool available really. I'd love to hear someone prove me wrong. [DL] Here's a paper that long ago destroyed the myth that Tcl is bad for CGI. http:expect.nist.gov/doc/cgi.pdf . Since this paper was written, quite a bit of software and other approaches have been created to make Tcl-based CGI programming quite pleasant. ---- [Category Internet]