7Script - Dynamic database driven web sites made easy

Topics: 

In the early history of the Web I had a twinkling of an idea to build dynamically generated web sites. One in particular I built, http://reiki.7gen.com/directory/ -- well, it is an overwhelming success of sorts allowing Reiki practitioners to register and announce themselves as Reiki practitioners. At the time I had formed the idea to build this kind of web site (1997) the tools to do so were either nonexistent or very primitive (cough, perl, cough, cough). It's possible PHP had begun development by then since I remember evaluating it and being very underwhelmed, and in any case my hosting provider only supported CGI scripts (barely). As a fan of TCL I wanted to use that language and set out on this line of development.

Accessing the 7script project code: You can download a complete tarball: http://audio.davidherron.com/7script/7script.tar.gz or you can access a subset in the mercurial repository at: http://hg.davidherron.com/index.cgi/7script/

I threw together a couple useful tools

  1. cgic: a wrapper which exposes CGI variables in TCL
  2. mysqltcl: a TCL wrapper for the then-nascent MySQL database engine
  3. miscellaneous other TCL modules which appeared they would be useful, but in the end I never used

During the development I grew this idea that it could become a commercialized programming platform and in my delusions of grandeur I chose the name "7 script". A few years before there was a wave of popularism of what was then called "4th generation programming languages" and as I owned "7gen.com" (representing '7 generations') I thought 7script could be a 7th generation programming language. That's what happens when a geek tries to do marketing. Anyway I did use 7script for several years on the Reiki Practitioner Directory but eventually rewrote it in PHP for several reasons.

It has some featuritis which I've never seen elsewhere and which I think is superior to the way loops are handled in other HTML processing systems. A common sort of thing is to have a database query you wish to represent as rows in a table. The general case is to present a list of tuples as rows in a table. In 7script this is handled like so:

  
Environment variables

<{
7script foreach envar [array names env ] {

}
}>

Env Variable Value
<$arg> <$env($envar)>

The unique and interesting thing here is how the body of the "7script foreach" command is itself HTML code which itself can be evaluated by the 7script interpreter. Let's pull this apart a little bit to make it clearer.

In 7script you begin a block of 7script code using "<{" and this is equivalent to the "<?" marker which is standardized in the other systems. You end a block using "}>" which is likewise the equivalent to the "?>" marker used in the popular systems. In 7script the initial context is to use HTML syntax, just as in PHP and the other systems and of course to do program code you have to escape into a context where program statements are allowed rather than HTML tags. In 7script, as I said, you escape into program code with "<{...code...}>" and in other languages it is instead "<?...code...?>".

Where 7script differs is that it puts commands into TCL whose bodies are in the HTML context. Look again at the above snippet, the beginning context is HTML, then "<{" switches context to TCL, then "7script foreach... {" switches context to HTML again. The HTML in this case contains a couple variable references like "<$arg>" but it could just as easily contained a "<{...code...}>" sequence, to switch again to the TCL context. The 7script parser allows HTML and TCL contexts to be nested arbitrarily deep with the only limitation being the execution environments ability to handle stack size.

For example this code snippet generates a list based on data in a database:-

      
<{
set items ""
if {[mysqlsel $db "SELECT itemDesc FROM table WHERE id=$id"] > 0} {
mysqlmap $db {itemDesc} {
lappend items $itemDesc
}
}
7script foreach item $items {
<{
mysqlsel $db "SELECT name,email FROM items WHERE id=$item"
mysqlmap $db {name email} { }
return ""
}>
"> <$name> <<$email>>
}
}>