-
Notifications
You must be signed in to change notification settings - Fork 0
jtlc and JXL Reference
var compiled_template = dojox.jtlc.compile( template, language, options );
Accepts template as its first argument and the language description (such as an instance of dojo.jtlc.JXL
) as its second argument. Returns the compiled evaluator function for the template or throws an exception in case of errors.
The third, optional argument of this function is used to inject properties directly into the compiler state (the language
object serves as its prototype and is not modified during compilation). This is a mechanism provided for the benefit of derived languages (e.g. CHT uses it to collect localizable strings from the template) and is of no interest for the JXL.
var jxl = new dojox.jtlc.JXL( settings );
Instantiates language description for JXL that can be customized by providing an optional property bag as an argument. The following are the settings recognized by the JXL:
- elideNulls
- When
true
, null values are not placed into array or dictionary sinks but are thrown away instead (with their corresponding keys in case of a dictionary). - failOnDuplicateKeys
- When
true
, an attempt to insert a duplicate key into the dictionary sink results in an exception. - singletonQuery.failOnNoResults
- Set to
true
to verify that queries in singleton contexts produce at least one result or throw an exception otherwise. - singletonQuery.failOnManyResults
- Set to
true
to verify that queries in singleton contexts produce no more than one result or throw an exception otherwise. - queryLanguage
- By default this option is set to
dojox.json.query
. You may substitute a query language compiler with compatible API. - replaceLanguage
- By defualt this option is set to
dojo.replace
. You may substitute a formatting function of your own with compatible API.
Note that default settings always favor performance over other concerns; turning on additional checking in the code is likely to make it somewhat more complex and, as a result, slower.
In JXL a literal is any value that is not an object with compile()
method defined.
{
key0:
input0 [,
… keyN:
inputN ]}
Object literals are sinks producing dictionaries (anonymous Javascript objects). By default, all inputs of an object literal are evaluated in singleton mode and the resulting values inserted into the resulting dictionary with literal key values. In order to populate a dictionary with keys generated from an input sequence, use the setkey
primitive within a sub-template enclosed in many
. In this case the key associated with this sub-template within the literal will be ignored and the computed value will be used instead.
[
input0 [,
… inputN ]]
Array literals are sinks producing anonymous Javascript arrays. By default, each input of an array literal is evaluated in an iterative context of its own. In order to evaluate a singleton sub-template and put its value into an array, enclose the sub-template within one
.
Note that array literals themselves are not generators and should not appear in an iterative context even though they establish an iterative context of their own inside the brackets. In order to use the value produced by an array literal as a generator, enclose it in from
.
String literals may appear in place of a sub-template anywhere in JXL. They are interpreted differently depending on the context: in the context of a singleton, the string is taken to be an inline expression as if it were enclosed in an expr
tag. In an iterative context, the string is assumed to be a query without additional parameters, which is to say, an equivalent of query( "string", current() )
.
Numeric and boolean literals are always interpreted as if they were enclosed in quote
, consequently, they may not appear in an iterative context.
Values with the type of function are treated as if they were enclosed in bind
.
In order to simplify construction of JXL trees, all JXL tag definitions consist of a creator function and a constructor function. Their relationship can be expressed as:
function creator( args )
{
return new constructor( args );
}
Creator functions for JXL tags are defined in the namespace dojox.jtlc.tags
, the following text will assume
var t = dojox.jtlc.tags;
for the sake of brevity. The users of the library do not access constructor functions directly, only the creator functions; if extending an existing tag is desired, the constructor functions can also be found within this namespace with the same names except for the prepended underscore character.
t.acc( initial_value )
Ensures that the value of its argument (usually a constant) is stored in a local variable (accumulator). Usually used as part of an aggregation construct such as t.expr( '$1+=(some expression)', input, t.acc(0) )
. It is not an error to use acc
in an iterative context but the tag will have no effect as the accumulator will be overwritten by the next iteration.
t.arg( index )
Returns one of the arguments passed into the evaluator of the template. While current
defaults to iterating over t.arg(0)
, the two are not equivalent: arg
is not by itself a generator and should be enclosed in from
to work as one. The argument of arg
should be a numeric value.
t.bind( function_value, input0 ... inputN )
Evaluates all of the input arguments, then applies the function
to them. In the iterative context the function is called once for every iteration with input0
treated as the generator and the rest of the arguments evaluated only once (in singleton contexts of their own). If no input arguments are provided, bind
assumes that the function is applied to current input.
t.current()
In a singleton context, returns value of the current input. Current input defaults to the value of t.arg(0)
but may be temporarily reset to different objects in a sub-template enclosed in primitives such as each
, group
and setkey
. In an iterative context, t.current()
serves as a generator of values from current input and may cause a runtime error if current input is not an array.
t.defined( input )
Serves as a filter passing only the defined values (i.e. values whose typeof
is not equal to 'undefined'
) from the input
, potentially reducing the length of the resulting sequence. Should not be used outside of iterative contexts.
t.each( input0 ... inputN )
Performs nested iterations by evaluating its first argument in iterative mode with current input set to each of the values generated by the second argument in turn and so on. Thus the rightmost argument forms the outermost iteration and the leftmost argument forms the innermost iteration. This primitive can only be used
in iterative contexts and evaluates every one of its arguments in an iterative context of its own.
Note that each
does not nest sinks, only the iterations. In fact, its usual application is flattening hierarchies formed by nested arrays passed into the template.
When given only one argument, each
will evaluate it against every value generated from current input.
t.expr( expression, input0 ... inputN )
Evaluates its input arguments (a maximum of 10 is supported), then evaluates the inline expression
(a string constant), substituting values of the arguments for placeholder symbols $
, $0
through $9
and $#
:
-
$0
…$9
- Values of
input0
throughinput9
. - $
- In singleton context, equivalent to
$0
. In an iterative context, current value generated byinput0
. - $#
- Sequence number of current value in an iterative context. Not defined in singleton contexts.
If the expression contains no placeholder strings and begins with an identifier, expr
assumes the latter to be a property reference relative to the current input and prepends $.
to it.
If no input arguments are provided, the expression
is evaluated as if t.current()
was supplied as input0
. Note that expr
is entirely similar to bind
except that bind
refers to a function outside of the template’s evaluator and expr
injects Javascript code directly into the evaluator’s body. In particular, arguments input1
through inputN
are evaluated only once even when expr
itself is in iterative context.
t.from( input )
Evaluates the input argument as a singleton and generates values from the resulting array or property values from the resulting dictionary. Applying from
to t.current()
has no effect because current
already serves as a generator in iterative contexts.
t.group( keys, body, input )
Provides SQL-like grouping capability by evaluating its body
repeatedly over subsequences formed from input
. The subsequences are established by evaluating the keys
— which should be either a single sub-template or an array of subtemplates, typically inline expressions — over each element of the sequence and comparing the results. The longest contiguous subsequence of generated values where keys are equal forms a group. The body
is then evaluated with current input set to the entire group.
The group
primitive can be used only in iterative contexts; it generates values returned by the body
: one value per group.
Note that for the grouping to work properly the input sequence should already be ordered in respect to the keys, so usually group
is applied to the
results produced by a query
. However, the user is left free to group sorted sequences originating elsewhere.
If the input
argument is omitted, current input is assumed.
t.keys( input )
Generates keys from the input
: property names if the value of input
is a dictionary (i.e. a non-array object), indices if it is an array. If input
is omitted, current input is used. Cannot be used outside of an iterative context.
t.last( input )
Serves as a special type of sink, returning only the last value generated by input
. Usually used for aggregation purposes. If input
is omitted, current input is used.
t.many( input )
Evaluates its input in an iterative context established for that purpose; if many
appears within an externally established iterative context it does not modify the behavior of its input in any way and simply passes on all the values it may return.
t.one( input )
Evaluates its input in a singleton context of its own when used within an externally established iterative context, effectively working as a generator that returns a single value.
t.query( query_text, input0 ... inputN )
Executes a query over specified inputs; each of the arguments input0
… inputN is evaluated as a singleton. By default, the @query_text
is pre-compiled with dojox.json.query()
; changing the queryLanguage
setting allows the user to use another query language implementation with a compatible API.
In iterative contexts, query
works as a generator returning individual matches. In singleton contexts query
assumes that one and only one result should be produced, which is returned on its own. If there are no matches, the result will have an “undefined” value; if there is more than one match only the first one will be used. This default behavior may be modified with the settings singletonQuery.failOnNoResults
and singletonQuery.failOnManyResults
.
Using query
without input arguments applies the query to current input (treated as a single value).
t.quote( value )
Returns value
as is (i.e. the jtlc does not get a chance to try and compile it), whether it it is a Javascript object, an array or a string.
t.replace( format_string, input )
Formats and returns its input by performing substitutions specified by the format_string
which should be a string value.
By default, replace
uses dojo.replace()
; user can change this behavior with the replaceLanguage
setting.
If the input argument is omitted, replace
works with current input.
t.setkey( body, input )
Changes the key (property name) under which the computed values will be stored in a dictionary sink. The input
argument is evaluated first, then body
is evaluated as a singleton with current input set to the value obtained by evaluating the input
; usually, the body consists of a replace
possibly in combination with expr
. The result returned by evaluating the body
is used as the key, the value returned by the input
is passed on.
The setkey
primitive can be used both within singletons and iterative contexts, but makes little sense in the former. Without the input
argument, setkey
operates on current input.