{"id":28194326,"url":"https://github.com/humansinput/toolatra","last_synced_at":"2026-01-24T10:33:54.781Z","repository":{"id":128773816,"uuid":"209589449","full_name":"humansinput/toolatra","owner":"humansinput","description":"Sinatra-like micro web framework for Tcl","archived":false,"fork":false,"pushed_at":"2020-06-01T16:45:24.000Z","size":94,"stargazers_count":21,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2026-01-23T21:41:14.862Z","etag":null,"topics":["html","sinatra","tcl","tcl-extensions","tcl-tk","toolatra","web","web-framework"],"latest_commit_sha":null,"homepage":null,"language":"Tcl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/humansinput.png","metadata":{"files":{"readme":"README.asciidoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-19T15:34:19.000Z","updated_at":"2025-12-16T10:33:59.000Z","dependencies_parsed_at":"2023-04-29T17:31:32.121Z","dependency_job_id":null,"html_url":"https://github.com/humansinput/toolatra","commit_stats":null,"previous_names":["humansinput/toolatra","tenfensw/toolatra"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/humansinput/toolatra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humansinput%2Ftoolatra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humansinput%2Ftoolatra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humansinput%2Ftoolatra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humansinput%2Ftoolatra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/humansinput","download_url":"https://codeload.github.com/humansinput/toolatra/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humansinput%2Ftoolatra/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28725374,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T10:24:43.181Z","status":"ssl_error","status_checked_at":"2026-01-24T10:24:36.112Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html","sinatra","tcl","tcl-extensions","tcl-tk","toolatra","web","web-framework"],"created_at":"2025-05-16T13:11:53.042Z","updated_at":"2026-01-24T10:33:54.750Z","avatar_url":"https://github.com/humansinput.png","language":"Tcl","funding_links":[],"categories":[],"sub_categories":[],"readme":"image::logo.png[]\n\n= Toolatra\n\nhttps://wiki.tcl-lang.org/page/Toolatra\n\nThe simplicity of Sinatra brought to Tcl.\n\n[source,tcl]\n----\npackage require Toolatra\n\nget / {\n\tshow \"Good morning!\"\n}\n\nrun\n----\n\n\n*Toolatra* is a micro web framework that is very similar to Sinatra, but is ported to Tcl.\n\n== What does it have?\n[squares]\n- Sinatra-like syntax\n- A module that provides a fully-featured template engine\n- Built-in web server that integrates easily with Nginx or Apache\n- A module for generating and validating authorization tokens\n\n== Installation\n=== On macOS\n\n[source,bash]\n----\n$ tclsh8.5 install-macos.tcl\n----\n\n=== On Ubuntu Linux\n\n[source,bash]\n----\n$ sudo sh\n$ mkdir -v /usr/share/tcltk/toolatra\n$ cp -r -v *.tcl /usr/share/tcltk/toolatra/\n$ exit\n----\n\n== Usage\nHandling a GET request to a specific path:\n\n[source,tcl]\n----\npackage require Toolatra\n\nget / {\n\tshow {Hello there, stranger!}\n}\n\nrun\n----\n\nIf you save and run this file with tclsh and then go to http://127.0.0.1:5050, you should see ``Hello there, stranger!``.\n\n_SPOILER!_ Specifying the port number on which the server should be ran to the ``run`` command will start Toolatra's server on that port.\n\nThrowing HTTP errors:\n\n[source,tcl]\n----\npackage require Toolatra\n\nget /this-will-cause-an-error {\n\terror 404\n}\n\nrun\n----\n\n\nBy 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 ``/\u003cHTML error code here\u003e``. Example:\n\n[source,tcl]\n----\npackage require Toolatra\n\nget /404 {\n\tshow \"Whoops, an error has occured.\"\n}\n\nget /this-will-cause-an-error {\n\terror 404\n}\n\nrun\n----\n\nServing additional headers:\n\n[source,tcl]\n----\npackage require Toolatra\n\nget / {\n\theader Content-type text/plain\n\tshow {Look, I'm plain text!}\n}\n\nrun\n----\n\nUsing templates:\n\n[source,tcl]\n----\npackage require Toolatra\npackage require ToolatraTemplates\n\nget / {\n\tetcl index.html [dict create name Tim]\n}\n\nrun\n----\n\nExample contents of ``index.html`` (it must be located in ``templates`` folder):\n\n[source,html]\n----\n\u003ch1\u003eHello there, @name@!\u003c/h1\u003e\n\u003cp\u003eDid you know that I can run Tcl code from here? Just look: 2 + 2 = @expr {2+2}@\u003c/p\u003e\n----\n\nSpeaking 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);\n\n[source,tcl]\n----\npackage require Toolatra 19.12\npackage require ToolatraMustache 20.06 ;# needed for Mustache templates to work\n\nget / {\n\tmustache greeter.html [dict create name Tim]\n}\n\n----\n\nExample contents of ``greeter.html.mustache`` located inside the ``templates`` folder:\n\n[source,html]\n----\n\u003ch1\u003eHello again, {{name}}!\u003c/h1\u003e\n----\n\nServing dynamically-generated binary data:\n\n[source,tcl]\n----\npackage require Toolatra 19.12\n\nget / {\n\tset binDtDesc [open a.out r]\n\tfconfigure $binDtDesc -translation binary -encoding binary\n\tset ctnt [read $binDtDesc]\n\tclose $binDtDesc\n\tbshow $ctnt application/octet-stream ;# or brender\n}\n----\n\nAccessing query string parameters:\n\n[source,tcl]\n-----\npackage require Toolatra\npackage require ToolatraTemplates\n\nget / {\n\tif {[dict exists $params name]} {\n\t\tshow \"Hello, [dict get $params name]!\"\n\t} else {\n\t\tetcl form.html\n\t}\n}\n\nrun\n-----\n\n``form.html`` template:\n\n[source,html]\n----\n\u003cform method=GET action=/\u003e\n\u003cp\u003eYour name: \u003cinput type=\"text\" name=name /\u003e\u003c/p\u003e \u003cbutton type=submit\u003eGreet me!\u003c/button\u003e\n\u003c/form\u003e\n----\n\nThis Tcl wiki page contains some useful examples on using templates and layouts: https://wiki.tcl-lang.org/page/Toolatra\n\nAccessing header values:\n\n[source,tcl]\n----\npackage require Toolatra\n\nget / {\n\tif {[dict exists $params User-Agent]} {\n\t\tshow [dict get $params User-Agent]\n\t} else {\n\t\tshow None\n\t}\n}\n\nrun\n----\n\nRedirecting to other pages:\n\n[source,tcl]\n----\npackage require Toolatra\n\nget / {\n\tredirect http://example.com\n}\n\n\nrun\n----\n\nHandling POST requests with data:\n\n[source,tcl]\n----\npackage require Toolatra\n\npost / {\n\trender \"Data sent: $rawData\"\n}\n\nget / {\n\trender \"Params/headers sent: $params\"\n}\n\nrun\n----\n\nHandling cookies:\n\n[source,tcl]\n----\npackage require Toolatra 19.12\n\nget / {\n\tif {[cookie token] != {}} {\n\t\tshow \"Cookie 'token' is set to [cookie token]\"\n\t} else {\n\t\tredirect /settoken\n\t}\n}\n\nget /settoken {\n\tcookie token [expr {int(rand() * 9999)}]\n}\n----\n\nAuthorization example:\n\n[source,tcl]\n----\nset toolatra_auth \",(!%\" ;# this is a 4-digit string that will be used to later encode the tokens that ToolatraAuth produces\n\npackage require Toolatra 19.12\npackage require ToolatraTemplates 19.11\npackage require ToolatraAuth 19.12\n\nget / {\n\tset cv [cookie authToken]\n\tif {! [tokenValid $cv]} {\n\t\tredirect /login\n\t} else {\n\t\tredirect /greet\n\t}\n}\n\nget /login {\n\tif {! [dict exists $params nm]} {\n\t\tetcl form.html\n\t} else {\n\t\tset name [dict get $params nm]\n\t\tset 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\n\t\tcookie authToken $tkn\n\t\tredirect /greet\n\t}\n}\n\nget /greet {\n\tset tkn [cookie authToken]\n\tif {! [tokenValid $tkn]} {\n\t\tredirect /login\n\t} else {\n\t\tset name [tokenValue $tkn]\n\t\tshow \"Greetings, $name!\"\n\t}\n}\n\nrun\n----\n\nwhere ``form.html`` is:\n\n[source,html]\n----\n\u003cform\u003e\n \u003cp\u003eTo continue, please enter your name.\u003c/p\u003e\n \u003cp\u003eName: \u003cinput type=text name=nm /\u003e\u003c/p\u003e\n \u003cbutton type=submit\u003eNext\u003c/button\u003e\n\u003c/form\u003e\n----\n\n== License\nAs always, MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhumansinput%2Ftoolatra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhumansinput%2Ftoolatra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhumansinput%2Ftoolatra/lists"}