AMG: This page contains example pages and applications for the Wibble web server. There may be some overlap with the Wibble zone handlers page. If all you have is a zone handler, put it in the zone handlers page. If you are explaining it in the context of a complete application, put it here. If you're showing off a useful modification of Wibble, maybe put that here too. And if you have a sample page or template, that's also welcome here.
AMG: Put this in a file called index.html.tmpl and see what happens.
% dict set response header content-type text/html <html><head><title>Hello from Wibble! - $uri</title></head><body> % set rand [expr {rand()}] % if {$rand > 0.5} { random=[format %.3f $rand] > 0.5<br/> % } else { random=[format %.3f $rand] <= 0.5<br/> % } time/date=[clock format [clock seconds]]<br/> milliseconds=[clock milliseconds]<br/> clicks=[clock clicks]<br/> % if {[info exists query] && ![dict exists $query noiframe]} { <iframe src="?noiframe" width="100%"/> % } </body></html>
AMG: Step 1. Make a directory, then create a file called wibble.tcl in that directory. Paste the Wibble implementation into the file. For this example, I used this version: [L1 ]. (Later versions may be incompatible, and I may forget to update this example!)
Step 2. Create a file in the same directory called index.html.tmpl with the following contents:
% dict set response header content-type text/html % % if {[dict exists $header cookie sessionid ""]} { % set sessionid [dict get $header cookie sessionid ""] % upvar #0 sessions($sessionid) session % } % % set now [clock seconds] % % if {![info exists session]} { % set sessionid [format %llX [string reverse\ % [string range [expr rand()] 2 end]]] % upvar #0 sessions($sessionid) session % set timeout 60 % dict set response header set-cookie\ % sessionid=$sessionid\;Max-Age=$timeout\;Version=1 % dict set session expiration [clock add $now $timeout seconds] % after [expr {$timeout * 1000}] [list apply {{sessionid} { % unset -nocomplain ::sessions($sessionid) % }} $sessionid] % } % % if {[dict exists $post imagetitle ""] % && [dict exists $post imagedata ""] % && [dict exists $post imagedata content-disposition filename] % && [dict exists $post imagedata content-type ""] % && [string length [dict get $post imagedata ""]]} { % set imagetitle [dict get $post imagetitle ""] % set imagefilename [dict get $post imagedata content-disposition filename] % set imagetype [dict get $post imagedata content-type ""] % dict set session imagetitle $imagetitle % dict set session imagedata [dict get $post imagedata ""] % dict set session imagefilename $imagefilename % dict set session imagetype $imagetype % } elseif {[dict exists $session imagetitle]} { % set imagetitle [dict get $session imagetitle] % } else { % set imagetitle "My Image" % } % <html><head><title>Image file upload test</title></head><body> <form method="post" enctype="multipart/form-data"> <table border="1"><tr><th> Session ID </th><td> [enhtml $sessionid] </th></tr><tr><th> Expiration </th><td> % set expiration [dict get $session expiration] [enhtml [clock format $expiration]], [expr {$expiration - $now}]s left </th></tr><tr><th> Sessions </th><td> <table> % foreach id [lsort [array names ::sessions]] { % set expiration [dict get $::sessions($id) expiration] <tr><th> [enhtml $id] </th><td> [enhtml [clock format $expiration]], [expr {$expiration - $now}]s left </td></tr> % } </table> </th></tr><tr><th> Image title </th><td> <input type="text" name="imagetitle" value="[enattr $imagetitle]" /> </td></tr><tr><th> Image file </th><td> <input type="file" name="imagedata" /> <input type="submit" value="Upload Image" /> % if {[dict exists $session imagedata]} { </td></tr><tr><th> File name </th><td> [enhtml [dict get $session imagefilename]] </td></tr><tr><th> Type </th><td> [enhtml [dict get $session imagetype]] </td></tr><tr><th> Image </th><td> <img src="image" /> % } </td></tr></table> </form> </html>
Step 3. Create another file in the same directory called image.script with the following contents:
if {[dict exists $header cookie sessionid ""]} { upvar #0 sessions([dict get $header cookie sessionid ""]) session } if {[info exists session] && [dict exists $session imagetype] && [dict exists $session imagedata]} { dict set response header content-type [dict get $session imagetype] dict set response content [dict get $session imagedata] } else { dict set response status 404 }
Step 4. Run wibble.tcl using tclsh, wish, tclkit, or whatever you prefer. You're now up and running.
Step 5. Point your Web browser to http://localhost:8080/ , and upload images. Access the site from multiple browsers on multiple computers. If you have Firecookie [L2 ] or similar, try messing with your cookies. Edit the files you created. Look at the index.html.script file that Wibble generated from index.html.tmpl. Have fun.
AMG: AJAX long polling can be done in Wibble. Here, I'll show you. Make a file called delay.html and put it in your docroot:
<html><head><script type="text/javascript"> function delay() { if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); } else { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { document.getElementById("result").innerHTML = xmlhttp.responseText; } } document.getElementById("result").innerHTML = "Waiting..."; time = document.getElementById("time").value; xmlhttp.open("GET", "delay?time=" + time, true); xmlhttp.send(); } </script></head><body> <p>How long shall I wait?</p> <p><input type="text" id="time" /> milliseconds</p> <p><button type="button" onclick="delay()">Do It!</button></p> <div id="result" /> </body></html>
And another called delay.script:
after [dict get $query time ""] [resume timer] set start [clock milliseconds] suspend timer set finish [clock milliseconds] dict set response header content-type text/plain dict set response content "I waited for [expr {$finish - $start}] milliseconds."
Go to http://localhost:8080/delay.html , type a number in the box, click the button, and wait. ;^)