Rivet Tcl Commands and Variables
Starting with version 2.1.0 Rivet command set moved into the ::rivet namespace. In order to preserve out of the box compatibility with existing scripts, Rivet exports commands by default and makes them available for import into any namespace (global namespace included). Rivet's build system can be told not to export the command set by passing the switch --disable-rivet-commands-export to 'configure'. In the future we may change this option's default. Commands must be imported into another namespace with the command: namespace import -force ::rivet::* Whenever a new application is being developed and compatibility issues can be confined within specific files, it is recommended that commands be specified with their fully qualified names.
<?= ... ?> Shorthand construct for single strings output <?= $string ?> Description This construct is a simplified form to print a single string wherever needed in a .rvt template. The contruct is equivalent to writing the following line of Tcl code puts -nonewline $string The string argument to the shorthand construct can be any Tcl command returning a value See Hello World or Variable Access abort_code Returns the code passed to abort_page earlier during the request processing ::rivet::abort_code Description Usage of this command is meaningful only in a script set as AbortScript or AfterEveryScript. abort_code returns the value of the optional parameter passed to abort_page earlier in the same request processing. abort_page Stops outputting data to web page, similar in purpose to PHP's die command. ::rivet::abort_page abort code -aborting Description This command flushes the output buffer and stops the Tcl script from sending any more data to the client. A normal Tcl script might use the exit command, but that cannot be used in Rivet without actually exiting the apache child process! abort_page triggers the execution of an optional AbortScript that has to be specified in the configuration. The value of the argument abort code can be retrieved with the abort_code command during the execution of AbortScript or AfterEveryScript, allowing the script to take appropriate actions in order to deal with the cause of the abort. The argument causes to return 1 when the current execution is the outcome of an abort condition. In other words this query is meaningful in code specified as AfterEveryScript to understand if an abort condition took place beforehand. apache_log_error log messages to the Apache error log ::rivet::apache_log_error priority message Description The apache_log_error command logs a message to the Apache error log, whose name and location have been set by the directive. Priority must be one of , , , , , , , or . apache_table access and manipulate Apache tables in the request structure. ::rivet::apache_table get set exists unset names array_get clear Description The apache_table command is for accessing and manipulating Apache tables in the request structure. The table name must be one of , , , , or . ::rivet::apache_table get tablename key When given the name of an Apache table and the name of a key , returns the value of the key in the table, or an empty string. ::rivet::apache_table set tablename key value ::rivet::apache_table set tablename list Stores the in the table under the key . For the list form, contains a list of zero or more pairs of key-value pairs to be set into the table . ::rivet::apache_table exists tablename key Returns 1 if the specified key, , exists in table , else 0. ::rivet::apache_table unset tablename key Removes the key-value pair referenced by from the table . ::rivet::apache_table names tablename Returns a list of all of the keys present in the table . ::rivet::apache_table array_get tablename Returns a list of key-value pairs from the table . ::rivet::apache_table clear tablename Clears the contents of the specified table. catch wraps core command catch ::rivet::catch script error_code_var_name options_var_name Description ::rivet::catch wraps the core language's same command adding some extra error handling needed by mod_rivet design. The rationale for Rivet to have its own ::rivet::catch reads as follows: within mod_rivet a script execution can be interrupted by either calling ::rivet::exit(deprecated) or ::rivet::abort_page. These commands implement a simple internal exception mechanism by returning a special error code so that execution is in turn handed down to the AbortScript and eventually to AfterEveryScript (if any of them is defined). Any code calling one of these commands which runs under control of the ::catch command would need to do this chore itself, checking the error info and in case throw the error again if it had been originated by one of mod_rivet's exceptions calls. This is what ::rivet::catch does hiding the implementation details provide a better and more compatibile way to handle this condition. This command is not meant to replace the core command, thus it's not exported from the ::rivet namespace and therefore has to be fully qualified. clock_to_rfc850_gmt create a rfc850 time from [clock seconds]. ::rivet::clock_to_rfc850_gmt seconds Description Convert an integer-seconds-since-1970 click value to RFC850 format, with the additional requirement that it be GMT only. cookie get, set and delete cookies. ::rivet::cookie set cookieName cookiValue -days expireInDays -hours expireInHours -minutes expireInMinutes -expires Wdy, DD-Mon-YYYY HH:MM:SS GMT -path uriPathCookieAppliesTo -secure 1/0 -HttpOnly 1/0 ::rivet::cookie get cookieName ::rivet::cookie delete cookieName ::rivet::cookie unset cookieName Description cookie gets, sets, unsets or deletes a cookie. When you get a cookie, the command returns the value of the cookie, or an empty string if no cookie exists. cookie delete will set the timeout value to -1 minutes - deleting the cookie in the browser. cookie unset will remove the defined cookie in the server (perhaps preparatory to checking/resetting the cookie). The command has a number of switches setting a cookie attributes debug A command to print strings, arrays and the values of variables as specified by the arguments. ::rivet::debug -subst<on|off> -separator<string> -option<value> -option<value> ... Description A command to make debugging more convenient print strings, arrays and the values of variables as specified by the arguments. Also allows the setting of an array called debug which will pick up options for all debug commands. env Loads a single "environmental variable" into a Tcl variable. ::rivet::env varName Description If it is only necessary to load one environmental variable, this command may be used to avoid the overhead of loading and storing the entire array. escape_sgml_chars escape special SGML characters in a string. ::rivet::escape_sgml_chars string Description Scans through each character in the specified string looking for any special (with respect to SGML, and hence HTML) characters from the specified string, and returns the result. For example, the right angle bracket is escaped to the corrected ampersand gt symbol. escape_shell_command escape shell metacharacters in a string. ::rivet::escape_shell_command string Description Scans through each character in the specified string looking for any shell metacharacters, such as asterisk, less than and greater than, parens, square brackets, curly brackets, angle brackets, dollar signs, backslashes, semicolons, ampersands, vertical bars, etc. For each metacharacter found, it is quoted in the result by prepending it with a backslash, returning the result. escape_string convert a string into escaped characters. ::rivet::escape_string string Description Scans through each character in the specified string looking for special characters, escaping them as needed, mapping special characters to a quoted hexadecimal equivalent, returning the result. This is useful for quoting strings that are going to be part of a URL. exit terminate execution and child process ::rivet::exit code Description Replaces Tcl's exit core command. ::rivet::exit interrupts execution of the current script and passes execution to AbortScript if such script is set. After AbortScript has finished and request processing completed the child process is forced to exit by calling Tcl_Exit producing the same final effect of the core command. During an AbortScript execution the exit condition can be detected if {[::rivet::abort_page -exiting]} { ...handle exit condition } ::rivet::exit has a single optional argument code. This value must be a positive integer number to be passed to Tcl_Exit. If any other value is given code is set to 0. The exit code can be obtained from the dictionary returned by ::rivet::abort_code [::rivet::abort_code] <== return_code code error_code exit We support this command in order to have a gentle way to terminate a request processing before actually exit the child process and avoid an abrupt interruption of a request that might leave an application in a inconsistent state. In some cases ::rivet::exit could be the only way to exit a process and force the Apache HTTP web server to start a fresh one. Moreover the core exit could be called from third parties software and you may not be aware of it. We thus decided to trap this command and give it the most gentle behavior still preserving the its basic purpose. Nonetheless we discourage the programmer to use such command, and suggest to focus on proper application design and avoid such a drastic way to bail out. If you need to restart the child processes from time to time we recommend to check the MaxRequests parameter in the prefork MPM documentation or the MaxRequestsPerChild configuration parameter headers set and parse HTTP headers. ::rivet::headers get set redirect add type numeric Description The headers command is for setting and parsing HTTP headers. ::rivet::headers get headername value Read arbitrary header names and values from output HTTP headers ::rivet::headers set headername value Set arbitrary header names and values into output HTTP headers ::rivet::headers sent Test internal status of the module and returns 1 if the HTTP headers have been already sent ::rivet::headers redirect uri Redirect from the current page to a new URI. Must be done in the first block of TCL code. ::rivet::headers add headername value Add text to header headername. ::rivet::headers type content-type This command sets the Content-type header returned by the script, which is useful if you wish to send content other than HTML with Rivet - PNG or jpeg images, for example. ::rivet::headers numeric response code Set a numeric response code, such as 200, 404 or 500. html construct html tagged text. ::rivet::html string arg Description Print text with the added ability to pass HTML tags following the string. Example: ::rivet::html "Test" b i produces: <b><i>Test</i></b> http_accept Parse HTTP Accept header lines ::rivet::http_accept -zeroweight -default -list http_accept_line Description Command for parsing HTTP Accept header lines that tell the server about preferences and/or capabilities of the browser (e.g. content language,media type, etc.). The following script ::rivet::http_accept returns a dictionary value in which every content preference is matched to its precedence value load_headers set language_precedence [::rivet::http_accept $headers(Accept-Language)] foreach lan [dict keys $language_precedence] { puts "$lan -> [dict get $language_precedence $lan]" } when run from a browser where 5 languages were chosen would output en-us -> 1 en -> 0.8 it -> 0.6 de-de -> 0.4 fr-fr -> 0.2 The -list switch would suppress the precedence values and the accepted fields are returned listed with decreasing precedence order. puts [::rivet::http_accept -list $headers(Accept-Language)] text/html application/xhtml+xml application/xml */* import_keyvalue_pairs Import an argument list into the named array ::rivet::import_keyvalue_pairs arrayName argsList Description key-value pairs, like "-foo bar" are stored in the array arrayName. In that case, the value "bar" would be stored in the element "foo" If "--" appears or a key doesn't begin with "-", the rest of the arg list is stored in the special args element of the array. Example: ::rivet::import_keyvalue_pairs keyvalue_map [list -a1 v1 -a2 v2 -a3 v3 -- 1 2 3 4 5] parray keyvalue_map keyvalue_map(a1) = v1 keyvalue_map(a2) = v2 keyvalue_map(a3) = v3 keyvalue_map(args) = 1 2 3 4 5 include includes a file into the output stream without modification. ::rivet::include filename_name Description Include a file without parsing it for processing tags <? and ?>. This is the best way to include an HTML file or any other static content. incr0 increment a variable or set it to 1 if nonexistent. incr0 varname num Description Increment a variable by . If the variable doesn't exist, create it instead of returning an error. incr0 functionality is provided by the native incr in Tcl >= 8.5, therefore this command is deprecated and kept as an interpreter alias only for compatibility. As such incr0 wasn't moved to the ::rivet namespace and it will be removed in future versions of Rivet. inspect Introspection command for Rivet configuration ::rivet::inspect configuration_section configuration_parameter Description ::rivet::inspect provides introspection into the running configuration of Rivet. Rivet's debug command uses it in order to gain insight into the configuration, but it can be used in any script. ::rivet::inspect can be called in 5 different forms With no argument the command returns a dictionary with 3 keys: server, dir, user. Each key is associated to a subdictionary carrying the configuration as set for that request. In this form the command is meant to support compatibility with previous versions of mod_rivet where three global arrays were created to be internally used by command ::rivet::debug. With the -all argument a dictionary carrying the whole configuration for that specific request is returned. If a configuration parameter is not set it's given the string undefined. Returned configuration paramenters are "ServerInitScript", "GlobalInitScript", "ChildInitScript", "ChildExitScript", "BeforeScript", "AfterScript", "AfterEveryScript", "AbortScript", "ErrorScript", "UploadMaxSize", "UploadDirectory", "UploadFilesToVar", "SeparateVirtualInterps", "HonorHeaderOnlyRequests" With one of the Rivet configuration directives listed above as single argument ::rivet::inspect returns the current value in the configuration record. Passing the argument "script" ::rivet::inspect returns a path to the current script in a similar way core command [info script] does. The basic difference is that the core command returns a relative path with respect to the current working directory, whereas mod_rivet's command returns the full path. Passing the argument "server" ::rivet::inspect returns a dictionary with these fields taken from the server record descriptor hostname: The server hostname admin: The admin's contact information errorlog: The name of the error log server_path: Pathname for ServerPath lassign_array Assign a list of values to array variables ::rivet::lassign_array value_list array_name array_variables Description lassign_array is an utility command inspired by the same Tclx command and with a close resemblance with Tcl's lassign for assigning list elements to variables. lassign_array first argument is a list of values to be assigned to an array that must be given as second argument. The remaining arguments are the array's variable names which will store as values the elements of the list. Variables names don't matching values in the list are given an empty string. Unassigned list elements are returned as a list. ::rivet::lassign_array {1 2 3 4} assigned_array a b c d parray assigned_array assigned_array assigned_array(a) = 1 assigned_array(b) = 2 assigned_array(c) = 3 assigned_array(d) = 4 set rem [::rivet::lassign_array {1 2 3 4 5 6 7} assigned_array a b c d] puts $rem 5 6 7 lempty Returns 1 if <list> is empty or 0 if it has any elements. This command emulates the TclX lempty command. ::rivet::lempty list Description Returns 1 if <list> is empty or 0 if it has any elements. This command emulates the TclX lempty command. lmatch Look for elements in <list> that match <pattern> ::rivet::lmatch -exact -glob -regexp list pattern Description Look for elements in <list> that match <pattern>. This command is a decent replacement for TclX lmatch command when TclX is not available In the following example a regular expression is matched against each element in the input list and a list containing the matching elements is returned ::rivet::lmatch -regexp { aaxa bxxb ccxxxxcc } {.+[x]{2}.+} bxxb ccxxxxcc load_cookies get any cookie variables sent by the client. ::rivet::load_cookies array_name Description Load the array of cookie variables into the specified array name. Uses array by default. load_env get the request's environment variables. ::rivet::load_env array_name Description Load the array of environment variables into the specified array name. Uses array by default. As Rivet pages are run in the namespace, it isn't necessary to qualify the array name for most uses - it's ok to access it as . load_headers get client request's headers. ::rivet::load_headers array_name Description Load the headers that come from a client request into the provided array name, or use if no name is provided. load_response load form variables into an array. ::rivet::load_response arrayName Description Load any form variables passed to this page into an array. If load_response is called without arguments the array is created in the scope of the caller. If the variables var1,var2,var3... having values val1,val2,val3... are passed to the page, the resulting array will be a collection mapping var1,var2,var3... to their corresponding values. load_response was inspired by the same NeoWebScript procedure in the way it deals with multiple assignments: if a variable is assigned more than once the corresponding array element will be a list of the values for the variable. This can be useful in the case of forms with checkbox options that are given the same name. This condition is signalled by the presence of an auxiliary array variable. Example: if a group of checkboxes are associated to the variable then response(var1) will store the list of their values and the array will also have the extra variable which can be tested with the usual [info exists response()] Calling load_response several times for the same array results in adding more values to the array at every call. When needed it is left to the caller to empty the array between two subsequent calls. lremove remove from a list elements matching one or more patterns ::rivet::lremove -regexp | -glob | -exact list pattern pattern pattern Description lremove removes from list list the first occurrence of an element matching one of the patterns listed in the command line. By specifying the option every occurrence of one the patterns is removed Pattern matching can be , style or following regular expressions (). These options are globally valid across the whole pattern list (default is glob style matching) ::rivet::lremove -all -regexp {aa e111 bab aa} aa e111 bab e111 bab ::rivet::lremove -all -regexp {aa e111 bab aa} aa "e\\d+" bab makeurl construct url's based on hostname, port. ::rivet::makeurl filename Description Create a self referencing URL from a filename. makeurl can be used in three ways With no arguments the current script URL is returned The argument is a relative path: the command returns the argument prefixed with the current script's URL The argument is an absolute path: the full URL to the resource is returned Example with an absolute path: ::rivet::makeurl /tclp.gif returns http://[hostname]:[port]/tclp.gif. where hostname and port are the hostname and port of the server in question. The protocol prefix is inferred from the protocol in the URL referencing the script. no_body Prevents Rivet from sending any content. ::rivet::no_body Description This command is useful for situations where it is necessary to only return HTTP headers and no actual content. For instance, when returning a 304 redirect. parray Tcl's parray with html formatting. ::rivet::parray arrayName pattern Description An html version of the standard Tcl parray command. Displays the entire contents of an array in a sorted, nicely-formatted way. Mostly used for debugging purposes. parse parses a Rivet template file. ::rivet::parse filename Description Like the Tcl source command, but also parses for Rivet <? and ?> processing tags. Using this command, you can use one .rvt file from another. raw_post get the unmodified body of a POST request sent by the client. ::rivet::raw_post Description Returns the raw POST data from the request. If the request was not a POST or there is no data, then "" - an empty string - is returned. redirect Interrupt processing and divert to a new URL ::rivet::redirect URL permanent Description ::rivet::redirect diverts the browser to a new URL and marks the redirection as either permanent in the browser local cache or non permanent (default). Calling ::rivet::redirect causes the script execution to interrupt and control passes to AbortScript, if such script is set, by calling ::rivet::abort_page and passing as abort code a dictionary with 2 keys: error_code: string literal 'redirect' location: the URL the browser will be redirected to ::rivet::redirect drives the redirection by setting the 301 (permanent = 1: permanent redirect) or 302 (permanent = 0: non permanent redirect) and attempts to discard the output the script might have already placed in the stdout channel buffer. The permanent argument can also be any of the other HTTP status codes. This is handy for returning one the 3xx status codes dedicated to the HTTP request redirection The command can fail if A flush stdout was called before ::rivet::redirect thus causing the HTTP headers to be sent and preventing any possibility to manipulate them The channel buffer was filled causing Tcl to flush the channel The stdout channel, like any Tcl channels, can be manipulated and if needed its internal buffer stretched. read_file Read the entire contents of a file and return it as a string. ::rivet::read_file file name Description This is a utility command which loads the entire content of a file and returns it as a result. try Catch error and exception conditions ::rivet::try script script handlers finally script Description ::rivet::try wraps the core language command and simply traps exceptions that might have raised by ::rivet::abort_page and ::rivet::exit to throw them again and thus causing AbortScript to be executed. If neither ::rivet::abort_page nor ::rivet::exit are called from script then any handlers specified in the command are tested for execution. Thus ::rivet::try can transparently be used as a replacement for Tcl's own try and it's needed if you want script to safely bail out to AbortScript This command is not exported from the ::rivet namespace and therefore has to be fully qualified. This script shows how ::rivet:try handles different exceptions or errors. You can drive this script within mod_rivet adding the arguments fail or abort or exit to its URL. You can handle the exit and abort cases with an AbortScript. See AbortScript <html><? ::rivet::try { if {[::rivet::var_qs exists exit]} { ::rivet::exit [::rivet::var_qs get exit] } elseif {[::rivet::var_qs exists abort]} { ::rivet::abort_page [::rivet::var_qs get abort] } elseif {[::rivet::var_qs exists fail]} { # this is just a non existent command wrong_command } else { puts "<b>OK</b>" } } on error {e o} { puts "catching error -&gt; $e<br/>" dict for {fd fv} $o { puts "$fd --&gt;&gt; $fv<br/>" } } ?></html> Placing this code in a file (try.rvt) on the web server DocumentRoot directory and setting for example the browser to http://localhost/try.rvt?fail=1. catching error -> invalid command name "wrong_command" -errorcode -->> TCL LOOKUP COMMAND wrong_command -code -->> 1 -level -->> 0 -errorstack -->> INNER {invokeStk1 wrong_command} UP 1 -errorinfo -->> invalid command name "wrong_command" while executing "wrong_command" ("::try" body line 9) -errorline -->> 9 unescape_string unescape escaped characters in a string. ::rivet::unescape_string string Description Scans through each character in the specified string looking for escaped character sequences (characters containing a percent sign and two hexadecimal characters), unescaping them back to their original character values, as needed, also mapping plus signs to spaces, and returning the result. This is useful for unquoting strings that have been quoted to be part of a URL. upload handle a file uploaded by a client. ::rivet::upload channel save data exists size type filename Description The upload command is for file upload manipulation. See the relevant Apache Directives to further configure the behavior of this Rivet feature. ::rivet::upload channel uploadname When given the name of a file upload , returns a Tcl channel that can be used to access the uploaded file. ::rivet::upload save uploadname filename Saves the in the file . ::rivet::upload data uploadname Returns data uploaded to the server. This is binary clean - in other words, it will work even with files like images, executables, compressed files, and so on. ::rivet::upload exists uploadname Returns true if an upload named uploadname exists. This can be used in scripts that are meant to be run by different forms that send over uploads that might need specific processing. ::rivet::upload size uploadname Returns the size of the file uploaded. ::rivet::upload type If the Content-type is set, it is returned, otherwise, an empty string. ::rivet::upload filename uploadname Returns the filename on the remote host that uploaded the file. ::rivet::upload tempname uploadname Returns the name of the temporary file on the local host that the file was uploaded into. ::rivet::upload names Returns the variable names, as a list, of all the files uploaded. See . url_script get the code of the URL referenced Tcl script or Rivet template ::rivet::url_script Description This command is used internally by the rivet central Tcl procedure (::Rivet::request_handling) executed by the default traditional code for HTTP requests processing. Unless you're implementing your own ::Rivet::request_handling procedure it's unlikely it can be of any use. var var_qs var_post get the value of a form variable. ::rivet::var get list exists number all ::rivet::var_qs get list exists number all ::rivet::var_post get list exists number all Description The var command retrieves information about GET or POST variables sent to the script via client request. It treats both GET and POST variables the same, regardless of their origin. Note that there are two additional forms of ::rivet::var: rivet::var_qs and ::rivet::var_post. These two restrict the retrieval of information to parameters arriving via the querystring (?foo=bar&bee=bop) or POSTing, respectively. ::rivet::var get varname default Returns the value of variable as a string (even if there are multiple values). If the variable doesn't exist as a GET or POST variable, the value is returned, otherwise "" - an empty string - is returned. ::rivet::var list varname Returns the value of variable as a list, one list element per reference. Radiobuttons or multiple selection listboxes are suited widgets which may return list data. If the result list is passed as a default value to the form package, one could also set index "__varname" to get it interpreted as a list. set response(countries) [::rivet::var list countries] set response(__countries) "" form form_request -defaults response form_request select countries -multiple 1 -values {USA Canada Mexico} form_request end ::rivet::var exists varname Returns 1 if exists, 0 if it doesn't. ::rivet::var number Returns the number of variables. ::rivet::var all Return a list of variable names and values. See . wrap Split a string on newlines. ::rivet::wrap string maxlen html Description For each line, wrap the line at a space character to be equal to or shorter than the maximum length value passed. If a third argument called "-html" is present, the string is put together with html <br> line breaks, otherwise it's broken with newlines. wrapline Split the line into multiple lines by splitting on space characters ::rivet::wrapline string maxlen html Description Given a line and a maximum length and option "-html" argument, split the line into multiple lines by splitting on space characters and making sure each line is less than maximum length. If the third argument, "-html", is present, return the result with the lines separated by html <br> line breaks, otherwise the lines are returned separated by newline characters. xml XML Fragments creation ::rivet::xml string tag descriptor tag descriptor ... Description Given a string and a variable number of tag descriptors return XML fragment made by nesting the tags with the same hierarchical order they are listed on the command line. The tag descriptors can be a one element list (the tag) or an odd-length list whose first argument is the tag namme and the remaining elements are interpreted as attribute name-attribute value pairs. ::rivet::xml can work as a replacement of ::rivet::html provided you take care of sending the string with command puts ::rivet::xml "a string" b u <== <b><u>a string</u></b> You can tell the tags which attributes they must have ::rivet::xml "a string" [list div class box id testbox] b i <== <div class="box" id="testbox"><b><i>a string</i></b></div> ::rivet::xml "text to be wrapped in XML" div [list a href "http://..../" title "info message"] <== <div><a href="http://..../" title="info message">text to be wrapped in XML</a></div>