An open API service indexing awesome lists of open source software.

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

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 Toolatra

get / {
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 Toolatra

get / {
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 Toolatra

get /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 Toolatra

get /404 {
show "Whoops, an error has occured."
}

get /this-will-cause-an-error {
error 404
}

run
----

Serving additional headers:

[source,tcl]
----
package require Toolatra

get / {
header Content-type text/plain
show {Look, I'm plain text!}
}

run
----

Using templates:

[source,tcl]
----
package require Toolatra
package require ToolatraTemplates

get / {
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 work

get / {
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.12

get / {
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 ToolatraTemplates

get / {
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 Toolatra

get / {
if {[dict exists $params User-Agent]} {
show [dict get $params User-Agent]
} else {
show None
}
}

run
----

Redirecting to other pages:

[source,tcl]
----
package require Toolatra

get / {
redirect http://example.com
}

run
----

Handling POST requests with data:

[source,tcl]
----
package require Toolatra

post / {
render "Data sent: $rawData"
}

get / {
render "Params/headers sent: $params"
}

run
----

Handling cookies:

[source,tcl]
----
package require Toolatra 19.12

get / {
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 produces

package require Toolatra 19.12
package require ToolatraTemplates 19.11
package require ToolatraAuth 19.12

get / {
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.