From ESM Wiki
Jump to: navigation, search



Template is an expression that defines rules to calculate string value of engine configuration options at each request processing transaction. Template is the means to parametrize configuration options with request-specific (runtime) values such as:

  • message sender, recipient, body part, etc.;
  • results from previous engines;
  • results from embeded functions.

Template is composed from the following elements:

  • string – text that will appear in result value “as is” (plain text).
  • macro – expression that starts from '$' (dollar) character is a macro and will be substituted at runtime with some calculated value.
  • escape – sequences of characters that will be replaced in result value with one special character. This is needed to have none-printable characters and characters that serves for macro definitions to appear in result value.

The syntax for a template is the following:

template = 1*(string | macro | escape)

Bellow is an example of a template:

SELECT COUNT(*) FROM `valid_recipient` WHERE `address`='${escape $recipient}'

In this example ${escape $recipient} is a macro with an argument. Argument in turn is a macro. Everything else is string.


String will appear “as is” in result value of a template. It is not marked or somehow separated – everything that is not macro or escape is considered to be a string (plain text). As a general principle in most cases utf-8 encoding is used for strings where international characters are allowed for result value. Here is an example of purely string template:

SET NAMES 'utf8'

The value of this option will always be “SET NAMES 'utf8'” regardless of runtime context.

Special case is handling of space characters (spaces (SP), tabs (HTAB), line feeds (LF), carriage returns (CR)) if they appear in a string. Templates are specified in XML as character data of corresponding element and spaces in data may be used to indent element data to make entire XML human readable. But this indentation spaces may be not desired in result value. That is why it is provided several variants of how spaces are handled:

  • Literally. Spaces are inserted into result value “as is” (as they appear in XML). This may be used if number of spaces between words is not important in result value (for example in MySQL queries).
  • Collapsed. Continuous sequences of SP's and HTAB's are replaced with single SP. If there are any LF or CR in a continuous sequence of spaces then LF and CR is leaved as they are but all SP's and TB's are removed.
  • Removed. All spaces are removed from result value. So template “here comes space” will evaluate to “herecomesspace”. If administrator wants to have spaces in result he/she must specify them explicitly using special macros (see Common Macros for details).

Space handling depends on specific configuration option and should be described in its specification.

The syntax for a string is the following:

string   = 1*(OCTET - special)    ; any none zero number of 8-bit values except special characters
special  = “\” | “$” | “{“ | “}”  ; all characters that must be escaped


Macro is a peace of string in a template that in result value will not appear “as is” but will be replaced with another string (macro value) generated at runtime. Each macro starts with '$' (dollar) character. Macro has a name which defines its type (i. e. defines how macro value will be generated). Some macros may have one or more arguments. Evaluation of such macro is started from evaluation of its arguments. Then obtained values of arguments are passed as parameters for evaluation of enclosing macro.

Here are a few examples:

$recipient           – macro with name “recipient” and without arguments
${sender}            – macro (bracketed form) with name “sender” and without arguments
${field condition}   – macro with name “field” and with 1 argument which is template “condition”
${escape $recipient} – macro with name “escape” and with 1 argument which is template “$recipient”

Full syntax for a macro is the following:

macro                  = macro_simple | macro_bracketed | macro_with_arguments;
macro_simple           = “$” macro_name;
macro_bracketed        = “${“ *space macro_name *space “}”;
macro_with_arguments   = “S{“ *space macro_name 1*(1*space argument) *space “}”;
macro_name             = 1*(ALPHA | DIGIT | “_” | “.”);
argument               = (“{“ template “}”) | template_without_space;
template_without_space = 1*(string_without_space | macro | escape);
string_without_space   = 1*(OCTET - special - space); same as string but without spaces inside
space                  = SP | HTAB | CR | LF;

Macro_simple form is used when macro doesn't have arguments and string (plain text) character that should immediately follow macro DOESN'T belong to valid macro name characters. In that case parse can correctly detect where macro ends and where string begins. For example in the following template:


macro $time6 may have macro_simple form because it is followed with “$” which doesn't not belong to valid macro name characters and thus correctly understood as a begining of next macro. From the other hand ${counter16} macro must have macro_bracketed form because it is followed with “.” which belong to valid macro name characters. If one would write $counter16.eml then parser will read macro with name counter16.eml and will generate an error because there is no such macro. What administrator really intended to do here was to have .eml extension for files but not this nonexistent macro. So one must use macro_bracketed form when a macro doesn't have arguments and string (plain text) character that should immediately follow a macro DOES belong to valid macro name characters.

In macro_with_arguments format arguments of a macro are separated from its name and from each other with spaces. That is why spaces are not allowed in strings of an argument. If spaces must appear in a string of an argument then this argument must be bracketed with curly braces “{}”. Here is an example of a macro with one argument:

${escape $sender} – Macro with one argument.

And here is an example of macro with three arguments:


Note that notation is multi-line. This is completely acceptable because newlines and other spaces are treated as argument separators and do not appear in result value.

Depending on a functionality domain macros can be classified as following:

  • Common Macros are embedded into core implementation and thus available in options of all current and future engines. For example $sender, $recipient, $ip, $not_empty, etc. List of all available common macros with their detailed description is here.
  • Engine Macros are provided with an engine implementation and thus available only in options of corresponding engine. For example $insert_id for mysql.query), action.full.path for file.save and other. List of available engine macros should be in a specification for a specific engine.
  • Variables are used to hold engine results and to insert them into templates of consequent engines in a pipeline and postprocessors.

Variable is constructed as follow:

variable = “$engines.” full_engine_id “.” result_id

For example


Name always starts with “engines.” prefix to provide a separate namespace for variables to not interfere with common and engine macros.


Escape sequences are needed to have some special and none-printable characters to appear in a result value. The syntax for escape sequence is:

escape 	    = “\” (escape_char | hex_value);
escape_char = OCTET - "x"                  ; any except "x"
hex_value   = "x" 2*2HEXDIGIT;             ; two hexadecimal digits

Rule for evaluating escape sequences is following:

\n -> LF
\r -> CR
\t -> HTAB
\a -> BELL
\v -> VTAB
other (except \xXX) are evaluated to ''escape_char'' itself
\xXX is evaluated to corresponding hexadecimal value


\\ \$ \r \n \xA2
Personal tools