CGI Services Architecture
Recent Pages

Environment Variables
Handling Concurrency
Template Processing
RDF Responses
RDF Messaging
URL Rewriting
File Uploads
Sample Authenticated Se ...
HTTP Cookies
Client Authentication

Links on Twitter
CSA Home
Table of Contents



User ID

Campaigns petition banner

Template Processing

In the Hello World example program, in particular at the line containing csaTemplate csaOk.html, the specified csaOk.html template is fetched by csaTemplate from $CSA_ROOT/forms/en_US/csaOk.html and sent to the client browser in response to the original request. Before the template is sent, a number of things occur inside csaTemplate. The most important one is tag substitution. That is, templates may contain special tags, that whenever are met by csaTemplate are replaced by the content of the corresponding environment variables, before the template is sent to the client. Such tags are ordinary names, surrounded by the special markers $[ and ]. If you look at the example csaOk.html, you will see that it contains one such tag, $[CSA_MSG_TEXT] (it is located towards the end of the file). If no value is associated with a certain tag, it will be replaced with a null string in the template that is sent to the client. Note that substitutions are done only against the data that travels towards the client, and that no changes occur to the original template file on disk.

As an example, let's say the program environment of Hello World contains the variable $HOME, having the value /home/goofy, and that we want such value to be displayed on the output template. For this to occur, the template must contain a $[HOME] tag, and upon serving the template to the client, csaTemplate will do the proper substitution.

For a substitution not to break HTTP and HTML/XML rules, some special characters in the original value need to be encoded. Strings that are to appear in an XHTML response should be XML-encoded, while those that are to be included in URLs need to be URI-encoded. It will then be up to the template programmer to request the most appropriate encoding, depending on the specific location in the template where the substitution is due to occur. By default, no encoding is performed on values during the substitution process, that is, tags are replaced with their literal values. If a certain encoding is desired, it can be specified by suffixing the tag with an appropriate encoding request, separated from the tag name by a colon ":". The available encoding requests are:

ISO, for HTML content.
JavaScript(TM), for program fragments embedded in HTML pages.
Turn white-space into "+" in URLs.
XML, for XML/XHTML content.
PATH_INFO, for PATH_INFO components in URLs.

Back to the $HOME example we will then have:


If we had a variable which value contained XML special characters, say SomeVar=<some-value>, then we would have:


Note that multiple encoding options may be specified at once, and they will be applied in order, i.e.:


Now it becomes clear why, in our csaOk.html template, the substitution tag is $[CSA_MSG_TEXT:x]: it is the XML-encoding request for the $CSA_MSG_TEXT variable that was set in the environment by csaPrintMsg, containing the message text to be displayed.

Since the rc shell exports every variable to the environment by default, substitution tags may refer to any variable that is known to the program name space. Anything that is present in the program environment can be captured by an equally-named tag on a page template. Although rc also axports function definitions to the environment, CSA by design does not make them available to the substitution process.

A note on tag names

Tag names inside $[...] in templates SHOULD always be simple strings, formed only by those character that are acceptable as Bourne shell variable names. That is, tags having names like $[HOME], $[my_tag] and $[goofy_123] are ok, while $[minnie!], and $[my@tag] are not. Actually, as an exception, the dot is also acceptable, as in $[my.tag].

Application-level encoding flags

Numeric encoding flags (1,2,3, etc.) are reserved for application-specific encoding types, and unless the corresponding _userencode() function is supplied by the application, they are all treated as NOOPs by CSA.

File inclusion tags

Beside marking a variable substitution point, tags can also cause whole files to be inserted in the template at the point where a tag occurs. For this to happen, a tag must be interpreted as a file path by the substitution engine. For instance, a tag like $[/etc/passwd] would cause csaTemplate to include your password file in the template, before the latter is sent to the client. Not very safe, but it would work To keep on the safe side, files are encoded in Base64 by default before being included at the point where the relevant tag occurs. If a different encoding, or no encoding at all, is desired, it can be done by suffixing the tag with an appropriate encoding option, separated from the tag name by a colon ":". As an example, we can request our /etc/passwd to be included as-is (that is without any encoding) by using the tag into $[/etc/passwd:c] (here "c" stands for ``CDATA''). The available encoding options are:

CDATA (character-data). That is, the requested file can be included verbatim in the specified context, with no need for encoding.
Same as "C", but CSA Processing Instructions are encoded, i.e. they are turned from (:tag:) into &amp;#40;:tag:). The different behaviour between "c" and "C" is of relevance only if CSA_ENABLE_CPI is set to true.
PCDATA (parsed character-data). The file needs to have a few special characters encoded before the inclusion, or the resulting templatemay be broken.

Here CDATA and PCDATA are taken from the XML terminology, and are loosely used with the same meaning.

Yet another file-related syntax is $[program|], whereby the name of the file to be included is expected to be returned by a back-end application-level program. Like any other file tags, also the $[program|] tag can take the encoding flags listed above for file-inclusion tags, that is , and so on. The program token is subject to strict inspection by the template processing code, to try and avoid security issues: it must be all lower-case, must begin with a letter, may contain only letters, numbers and hyphens, and it will be sought for only in CSA_ROOT/proclib. The called program shares the full environment space of the invoking CSA application, and any arguments that the program may possibly require will have to be read from the environment itself. No provisions have been established to pass any command-line arguments to program through the $[program|] tag, as that would complicate the tag syntax and could easily turn insecure. The CSA variable CSA_TPL_TMP is meant to provide the called program with a path to a temporary filename that the program MAY need to store the result into. The CSA_TPL_TMP file is removed by the CSA stack upon exit, so that the called program does not need to deal with that housekeeping issue. Whether the program writes to CSA_TPL_TMP or not, the string printed to STDOUT will have to be the full path to the file containing the result to be fetched by the file inclusion template processor.

Two-pass tags

So far, so good. In reality, however, the name of the file to be inserted is not known in advance, and it's name cannot therefore be hard-coded into the tag. Usually, the file name is contained in a program variable, say varname=/path/to/file, and the template will contain the tag $[varname]. But given the standard substitution mechanism, $[varname] would be replaced with the literal value /path/to/file by the substitution process, not by the file contents. To cope with this, the csaTemplate function can be called as follows:

  csaTemplate --eval varname template.html

This tells csaTemplate that whenever it encounters a $[varname] tag in template.html, the value associated with varname must be substituted first, as usual, but then a second substitution pass must be done on the resulting tag. Since varname contains /path/to/file, the first pass will turn $[varname] into $[/path/to/file], and this value will then be interpreted by the second pass as a file-inclusion directive. Starting with CSA version 1.0.4, two-pass tags are no longer limited to file tags, but may have any content. Additionally, a two-pass tag value is scanned for encoding flags in its value (see above); if flags are found they are used to override any possibly different flags that were specified in the template file. That is, if the template contains $[varname:c] and we set varname=somevalue:u, then $[varname:c] in the template will be replaced by the URI-encoded version of somevalue. The two-pass processing just described does not apply to $[program|] type tags.

If multiple file-inclusion tags must be eval'ed in this way, they can be passed to csaTemplate in a comma-separated list:

  csaTemplate --eval varname1,varname2,... template.html

Relative file tags

If a file tag contains a relative file path, that is , the specified file is considered to be relative to the HTML template directory $CSA_ROOT/forms/$CSA_LANG by default, or to whatever directory is specified with the --file-root option of csaTemplate. Starting with CSA version 1.0.4, file tags MUST always begin with either ./ or / (both possibly preceded by -, see below). Relative file tags in the form of $[path/to/file] are no longer supported. This was done to support two-pass non-file tag contents, such as varname='data:image/png;base64,...', where the value of the two-pass tag varname does not represent a file path even if it contains a / character.

No-replace file tags

If a file tag begins with a hyphen, such as -/path/to/file, then the target file is included but any replaceable tags that it may contain are left unchanged, i.e. they are not replaced by their values, and therefore no further lower-level inclusions may occur.

Trackbacks (0) | New trackback | Print

This Web Site is Copyright © 2007,2008,2009,2010 Carlo Strozzi, Some Rights Reserved
site map | recent changes | disclaimer