https://github.com/humansinput/toolatra
Sinatra-like micro web framework for Tcl
https://github.com/humansinput/toolatra
html sinatra tcl tcl-extensions tcl-tk toolatra web web-framework
Last synced: 5 months ago
JSON representation
Sinatra-like micro web framework for Tcl
- Host: GitHub
- URL: https://github.com/humansinput/toolatra
- Owner: humansinput
- License: mit
- Created: 2019-09-19T15:34:19.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2020-06-01T16:45:24.000Z (over 5 years ago)
- Last Synced: 2025-05-13T14:35:23.918Z (5 months ago)
- Topics: html, sinatra, tcl, tcl-extensions, tcl-tk, toolatra, web, web-framework
- Language: Tcl
- Size: 91.8 KB
- Stars: 20
- Watchers: 3
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.asciidoc
- License: LICENSE
Awesome Lists containing this project
README
image::logo.png[]
= Toolatra
https://wiki.tcl-lang.org/page/Toolatra
The simplicity of Sinatra brought to Tcl.
[source,tcl]
----
package require Toolatraget / {
show "Good morning!"
}run
----*Toolatra* is a micro web framework that is very similar to Sinatra, but is ported to Tcl.
== What does it have?
[squares]
- Sinatra-like syntax
- A module that provides a fully-featured template engine
- Built-in web server that integrates easily with Nginx or Apache
- A module for generating and validating authorization tokens== Installation
=== On macOS[source,bash]
----
$ tclsh8.5 install-macos.tcl
----=== On Ubuntu Linux
[source,bash]
----
$ sudo sh
$ mkdir -v /usr/share/tcltk/toolatra
$ cp -r -v *.tcl /usr/share/tcltk/toolatra/
$ exit
----== Usage
Handling a GET request to a specific path:[source,tcl]
----
package require Toolatraget / {
show {Hello there, stranger!}
}run
----If you save and run this file with tclsh and then go to http://127.0.0.1:5050, you should see ``Hello there, stranger!``.
_SPOILER!_ Specifying the port number on which the server should be ran to the ``run`` command will start Toolatra's server on that port.
Throwing HTTP errors:
[source,tcl]
----
package require Toolatraget /this-will-cause-an-error {
error 404
}run
----By default, Toolatra's ugly error handler will be used. To replace it with a custom one, just define a GET request handler with the path set to ``/``. Example:
[source,tcl]
----
package require Toolatraget /404 {
show "Whoops, an error has occured."
}get /this-will-cause-an-error {
error 404
}run
----Serving additional headers:
[source,tcl]
----
package require Toolatraget / {
header Content-type text/plain
show {Look, I'm plain text!}
}run
----Using templates:
[source,tcl]
----
package require Toolatra
package require ToolatraTemplatesget / {
etcl index.html [dict create name Tim]
}run
----Example contents of ``index.html`` (it must be located in ``templates`` folder):
[source,html]
----Hello there, @name@!
Did you know that I can run Tcl code from here? Just look: 2 + 2 = @expr {2+2}@
----Speaking of templates, you don't have to use Toolatra's template engine - you can use Mustache templates if you want in a pretty similar manner (you'll need ianka's mustache.tcl library installed first, though);
[source,tcl]
----
package require Toolatra 19.12
package require ToolatraMustache 20.06 ;# needed for Mustache templates to workget / {
mustache greeter.html [dict create name Tim]
}----
Example contents of ``greeter.html.mustache`` located inside the ``templates`` folder:
[source,html]
----Hello again, {{name}}!
----Serving dynamically-generated binary data:
[source,tcl]
----
package require Toolatra 19.12get / {
set binDtDesc [open a.out r]
fconfigure $binDtDesc -translation binary -encoding binary
set ctnt [read $binDtDesc]
close $binDtDesc
bshow $ctnt application/octet-stream ;# or brender
}
----Accessing query string parameters:
[source,tcl]
-----
package require Toolatra
package require ToolatraTemplatesget / {
if {[dict exists $params name]} {
show "Hello, [dict get $params name]!"
} else {
etcl form.html
}
}run
-----``form.html`` template:
[source,html]
----Your name:
Greet me!----
This Tcl wiki page contains some useful examples on using templates and layouts: https://wiki.tcl-lang.org/page/Toolatra
Accessing header values:
[source,tcl]
----
package require Toolatraget / {
if {[dict exists $params User-Agent]} {
show [dict get $params User-Agent]
} else {
show None
}
}run
----Redirecting to other pages:
[source,tcl]
----
package require Toolatraget / {
redirect http://example.com
}run
----Handling POST requests with data:
[source,tcl]
----
package require Toolatrapost / {
render "Data sent: $rawData"
}get / {
render "Params/headers sent: $params"
}run
----Handling cookies:
[source,tcl]
----
package require Toolatra 19.12get / {
if {[cookie token] != {}} {
show "Cookie 'token' is set to [cookie token]"
} else {
redirect /settoken
}
}get /settoken {
cookie token [expr {int(rand() * 9999)}]
}
----Authorization example:
[source,tcl]
----
set toolatra_auth ",(!%" ;# this is a 4-digit string that will be used to later encode the tokens that ToolatraAuth producespackage require Toolatra 19.12
package require ToolatraTemplates 19.11
package require ToolatraAuth 19.12get / {
set cv [cookie authToken]
if {! [tokenValid $cv]} {
redirect /login
} else {
redirect /greet
}
}get /login {
if {! [dict exists $params nm]} {
etcl form.html
} else {
set name [dict get $params nm]
set tkn [token $name] ;# the generated token will expire in 1 day, to specify the expiration date, specify the number of seconds as the second argument
cookie authToken $tkn
redirect /greet
}
}get /greet {
set tkn [cookie authToken]
if {! [tokenValid $tkn]} {
redirect /login
} else {
set name [tokenValue $tkn]
show "Greetings, $name!"
}
}run
----where ``form.html`` is:
[source,html]
----
To continue, please enter your name.
Name:
Next----
== License
As always, MIT License.