TH1
TH1 is the built-in scripting/templating language in Fossil.
It can be used in the header, stylesheet or footer within <th1>...</th1>
sections, or in the th1-setup
settings field.
It's a slim TCL variant (but a full TCL interpreter may be compiled in too).
See the Cookbook on TH1 or the
TH Manual.pdf for a proper overview.
The following is just a crude summary.
Basic syntax
Everything is a string. No really. The string is the fundamental datatype in TH1 / TCL.
Variables are often passed just by their literal varname. With a
$
prefix their value gets substituted or interpolated.set varname "something something" puts $varname
Literals are also strings. For instance
1
is a string,text…text
is a string and,&=asdf!
is a string.There are three ways to group things for substitution.
- In
"
double"
quotes any literal text can be grouped into a string, and$vars
will be interpolated. Double quotes can be escaped by\"
within. They cannot nest themselves, but within{}
or[]
subgroups. - Square brackets
[proc calls]
interpolate procedure call results. They also do so within"
double quoted strings. And of course they can be nested[expr 5*[expr [expr $x]+2]]
- Whereas
{...}
curly blocks are unparsed sections, can be nested with{}
themselves or[]
and""
. They're often used to defer literal code/string sections for later evaluation.
- In
Statements are interpreted line by line. The first string literal is the procedure to call.
funcname arg1 arg2 ...
Arguments can be literals, strings, variables, [proc ..] calls, etc. Trailing semicolons are optional. Some functions provide prefix arguments
-xyz
and--
flag separators, or?optional?
parameters.Expressions are only interpreted in the if {expr} block, or with
[expr 2*$x+1]
calls. They can't be used as statements all alone.Lists are a special variant of strings. Any string with spaces can be e.g. split-accessed via lindex. Curly braces can group further substrings/lists within. (Lists are actually pretty central to the TH1/TCL syntax. Command statements and their arguments are basically seen as lists too.)
Variable names of the form
$varname(xyzname)
are treated as arrays. You need to know/keep the array keys to utilize them in TH1.
Most control structures (e.g. if and proc) are implemented as procedure calls. To wrap code blocks
over multiple lines, the opening {
curly quote must be in the same statement line, and subsequent blocks
be chained with } {
thereafter.
Built-in TH1 functions
Also see https://www.fossil-scm.org/fossil/doc/trunk/www/th1.md for a more detailed list.
<style> main table td:nth-child(1) { width: 30% } main table tr:nth-child(2n) { background: #f7f7f7; } main table kbd { color: #311; font-weight: 500; } </style>
set VARNAME value | Defines a variable. The varname is noted without leading $ , but creates a $varname afterwards. The value can be a literal 123 number, or a "string" , or an [expr ...] or any other [ProcCall ...] of course. |
unset VARNAME | Undefines a variable by name. |
info exists VARNAME | Probes if a variable was defined. |
expr $x +-*/ <>!=< | Runs an expression, returns its result. This can be any combination of arithmetics, or comparisons, with variable names or literal strings. Usually used within [...] square brackets for interpolation. |
proc {args} {cmd} | Defines a new function. {args} is a space-separated list of parameter names, and {code} just a code block. |
catch {code} rc? | Runs a code block, but ignores any runtime errors. An optional varname parameter captures TH1_ERROR codes etc. |
if {expr} {body} elseif expr2 body2 else bodyN? | Tests an expression, and runs the code {body}. Can optionally list multiple elseif expressions and blocks, and a final else of course. Each expression can be a literal {$x >= 2} or a function result interpolation {[string length $var] >= 2} for example. |
for {init} {condition} {incr} {code-block} | Runs a code block multiple times. The {init} can be empty, the {condition} is usually a boolean comparison, and {incr} often {set cnt [expr $cnt+1]} . |
list a b c ... | Compacts multiple arguments into a list-string. A list is simply a space-separated string, or entries quoted with unparsed {...} curly sections. |
lindex list index | Returns an entry from a list-string. |
llength list | Counts the number of elements in a list-string. |
proc name {args} {code} | Declares a new function. The name is the literal procedure name. Args can be a space-separated list of argument varnames. And the {code} block... is the code block. |
rename oldcmd newcmd | Renames a declared function. |
break | Break statement. |
continue | Continue statement. |
ok | Ok statement. |
error | Error statement. |
return value? | Plain value return. Used in procedures of course. Can list an optional -code state (break, continue, ok, error) before the value. |
string compare $str1 $str2 | Compares strings (strcmp) for alpha-/numeric sorting. |
string first $needle $haystack | Finds first position of one string in another. Optional startindex as third param. |
string is alnum $string | Checks if string is completely alphanumeric, no special chars. |
string last $needle $haystack | Finds last position of needle in haystack string. |
string length $string | Returns length of string/variable. |
string range $str first end | Returns a substring of its input. String indicies start at 1. The END parameter can be larger than the actual string length. |
string repeat $str COUNT | Duplicates a string CNT times, returns the concatenated result string. |
string trim $str | Removes whitespace from string. |
string trimleft $str | Removes whitespace from string. |
string trimright $str | Removes whitespace from string. |
uplevel LEVEL {code} | Runs given code block in a different variable scope. Usually uplevel 1 {...} to run things in the global scope / prior function call in the chain. |
upvar LEVEL extvar local | Imports/aliases a variable name from a different variable scope, and can attach a new local name to it. |
breakpoint | Does nothing. Only used for debugging Fossil/TH1. |
Fossil functions
httpize "string" | Escapes a string for URL context. |
enable_output 1/0 | Allows to suppress further output. |
puts string | Prints a string to the page, pre-escapes HTML special characters. |
html string | Prints a raw string, so may contain actual HTML for display. |
wiki string | Uses the Wiki renderer to output a string. Thus fossil wiki markup will be converted to HTML. |
htmlize string | Escapes a string for HTML context. |
date | Returns current date and time string in UTC. With -local in current timezone. |
hascap letters | Probes permissions for currently logged in user. Argument can be a string of letter-wise capabilities (from Admin>User). |
anycap letters | Probes if any of the listed permission letters is allowed for current user. |
hasfeature setting | Checks which Fossil features were compiled in (can be one of: ssl, tcl, json, markdown, th1Docs, th1Hooks, tclStubs, useTclStubs). |
combobox name list lines | Prints a HTML combobox. |
linecount string max min | Counts linebreaks in string. |
repository | Return full path name to currently open fossil repository. |
checkout | Return full path name to opened checkout directory. |
trace message | Outputs/logs a debug message, if tracing is enabled. |
globalState setting | Returns other runtime states/paths/flags (can be one of: checkout, configuration, executable, flags, log, repository, top, user, vfs) |
getParameter name default? | Returns URL parameter with given name or position, or CLI parameter for th1-cmd-hooks. |
setParameter name value | Overwrites an URL parameter. |
reinitialize flags? | Restarts TH1 interpreter with initialization flags (bitmask of 1=need_config, 2=force_tcl, 4=force_reset, 8=force_setup). |
render string | Outputs rendered string. Templates can themselves contain TH1 code. |
styleHeader title | Outputs style header. (No idea what that is.) |
styleFooter | Outputs footer. |
artifact UUID filename? | Prints the raw artificat content by UUID or filename. |
utime | Elapsed CPU time for current fossil userland process in microseconds. |
stime | Elapsed CPU time for system calls. |
randhex N | Creates a string of random hexdigit pairs. |
query {SQL} {code} | Yay! Query Fossil SQL database. The SQL code can be put in curly braces {SELECT $varname} for implicit variable→parameter binding. The {CODE} automatically receives column names and values as $vars for each row. |
setting name | Returns Fossil configuration setting string. Preface with -strict to avoid ambigous setting name matches. |
regexp -nocase? exp string | Matches a string agains an extended regular expression (no regex delimiters). The -nocase flag an be noted before the regex string. Prefer {curly*} quoting for the regex. |
http url payload? | Sends a HTTP query. Target must be whitelisted by url-regexp in the settings. The optional payload would become a plain text POST body. Should return the HTTP response body as string. |
TCL Binding
tclReady | Tests if TCL was enabled and can be called from TH1 scripts. Only returns true after first tclInvoke seemingly. |
tclInvoke CMD args.. | Runs a TCL procedure from within TH1. |
tclExpr {expr} | Evaluates an expression via TCL, returns its result. |
tclEval args.. | Runs some TCL code. |
th1Expr args.. | Fetch TH1 value/expression from within TCL code. |
th1Eval args.. | Run TH1 from TCL context. |
TH1 Hooks
webpage_hook | Run prior rendering built-in webpages. Allows to render custom pages. |
webpage_notify | Run after successful page rendering. |
command_hook | Run prior command line actions. Allows to declare new fossil commands. |
command_notify | Run after normal CLI commands. |
Default variables
$project_name | Proj Name |
$title | Homepage |
$baseurl | http://fsl.example.org/repo/ |
$secureurl | http://fsl.example.org/repo/ |
$home | home |
$index_page | /home |
$current_page | /wiki/index |
$csrf_token | localhost |
$release_version | 1.31 |
$manifest_version | 4932465ecc |
$manifest_date | 2015-02-02 20:00:00 |
$compiler_name | gcc-4.9.0 |
$stylesheet_url | /style.css/142257204849324 |
$logo_image_url |
/logo/130387012349324 |
$background_image_url |
/background/133320697349324 |
$login | username |
$::cmd_name | co |
$::cmd_args | filename |
$::cmd_flags | |
$::web_name | home |
$::web_args | fossil ui |
$::web_flags | 1 |