7.0 KiB
EFTL language reference
This is a compact index derived from the documents currently under docs/. Re-check the PDFs when exact wording, diagrams, or edge behavior matters.
Documentation map
elixForms_Doc_EFTL.pdf: EFTL specification through the documented 3.1.0 changes, language behavior, attributes, control flow, and examples.elixForms_EFTLParser_syntax_rels.pdf: generated lexer/parser relationship diagrams.elixForms_TAG_Sintassi.pdf: positional syntax for the ElixFormsSCHEMAIDandGETVALUEBYTAGplugins.
Common lexical and structural rules
- EFTL uses square-bracket tags and requires properly nested, non-overlapping elements.
- A bodyless element ends with
/]; a block has matching opening and closing tags. - Attribute values are quoted. Attribute order is not semantically significant.
- The main specification says uppercase and lowercase tag spellings are interpreted equally and recommends lowercase style. The current implementation is largely uppercase-only.
- Text outside
[EFTL]...[/EFTL]is not processed. Text inside an EFTL root but outside an executable tag is emitted as user text where the grammar permits it. - Comments use
[!-- ... --]and may span lines. - The generated relationships include user text, ignored whitespace, CDATA, headers, comments, statements, code blocks, and output blocks. Consult the diagram PDF before enforcing a new parent/child restriction.
Root, directives, and context
| Construct | Form | Key rules |
|---|---|---|
| EFTL | [EFTL] ... [/EFTL] |
Root block; no documented attributes; a document needs at least one root to be processed. |
| HEADER | [HEADER name="..." value="..." type="..." /] |
Declares a directive. The documented directive is trimDocument, with boolean true or false. |
| LOG | [LOG] ... [/LOG] |
Writes evaluated content to the server log; no documented attributes. |
Predefined execution-context names include currentDateTime, defaultLocale, currentLocale, and requestId. Other values may be supplied by the calling service.
Variables and value functions
| Construct | Form | Key rules |
|---|---|---|
| VAR | [VAR name="..." type="..." unique="..." ] ... [/VAR] |
name identifies a context variable. Documented types: string, boolean, number, date, object, iterable. unique defaults to false and is meaningful only for iterable. |
| VALUE_OF | [VALUE_OF varname="..." index="..." /] |
Emits a variable value. index identifies the position for an iterable and may name another variable. |
| SIZE_OF | [SIZE_OF varname="..." /] |
Returns iterable size, otherwise 0. |
| IS_EMPTY | [IS_EMPTY varname="..." /] |
Tests missing, null, blank string, empty iterable, or empty map according to the documented rules. |
| IS_NOT_EMPTY | [IS_NOT_EMPTY varname="..." /] |
Logical negative of IS_EMPTY. |
| CONTAINS | [CONTAINS varname="..." value="..." /] or [CONTAINS varname="..."] ... [/CONTAINS] |
Supports string or iterable input. Attribute value and body are alternatives; value has priority when both exist. |
Do not require type merely because current examples commonly include it: some examples omit it. Resolve requiredness from the parser relations or runtime contract before emitting an error.
Transformations
| Construct | Form | Key rules |
|---|---|---|
| FORMAT | [FORMAT varname="..." type="..." /] or [FORMAT type="..." pattern="..."] ... [/FORMAT] |
varname takes precedence over the body. Documented formatting covers number and date families; number modes include currency, integer, double, percent, and generic. |
| SPLIT | `[SPLIT regex="..." emptyIfBlank="true | false"] ... [/SPLIT]` |
| TRIM | [TRIM varname="..." /] or [TRIM] ... [/TRIM] |
Trims a named variable or evaluated body. A found variable takes precedence; otherwise the body is evaluated. |
Control structures
- IF shape:
[IF] [CONDITION] ... [/CONDITION] [THEN] ... [/THEN] { [ELSE IF] ... [/ELSE IF] } [ELSE] ... [/ELSE] [/IF]. CONDITIONmust evaluate to boolean. There may be multipleELSE IFblocks and at most one finalELSE; both are optional.- WHILE shape:
[WHILE ...] [CONDITION] ... [/CONDITION] [DO] ... [/DO] [/WHILE]. - The WHILE section documents an optional
thresholdwith default and maximum32766, but also contains a sentence saying the tag has no attributes. Treat this as an explicit documentation inconsistency. - FOR shape:
[FOR varName="item" iterable="items"] ... [/FOR]. The loop variable exists during the loop and is removed afterward. - The FOR prose depends on both
varNameanditerable, but the generated relationship only shows a generic attribute node. Treat formal requiredness, attribute-name casing, duplicate/unknown attributes, null or non-iterable input, and shadowing as unresolved until confirmed against the runtime grammar.
Code blocks
| Kind | Form | Meaning |
|---|---|---|
| Assignment | [% target = expression; ... %] |
Mutates variables; documented statements end with ;. |
| Evaluation | [% expression %] |
Evaluates and returns a result, often boolean in CONDITION. |
| Output | [%= variable %] |
Writes a context variable; a missing variable is a runtime error. |
The expression language examples use assignment, equality/comparison, arithmetic, boolean operators, strings, numbers, booleans, and null. The PDFs do not provide a complete operator-precedence grammar; avoid inventing one without a runtime grammar source.
ElixForms TAG payloads
SCHEMAID is positional:
- position 0: plugin name
SCHEMAID; - position 1: schema ID;
- position 2: column reference;
- position 3:
IUQOID; - position 4: line terminator, with a space selecting the default;
- position 5: column separator;
- position 6: default value;
- position 7: date/time formatter;
- position 8: language (documented as currently unused).
Positions 0 through 4 must be present. Preserve commas for omitted intermediate optional positions.
GETVALUEBYTAG is positional:
- position 0: plugin name
GETVALUEBYTAG; - position 1: tag name;
- position 2: lookup type:
REQUEST,MODULE, orUSER_PROFILE; - position 3:
IUQOID; - position 4: weight/order option;
- position 5: column separator;
- position 6: format string.
The weight list in the prose and the final syntax example differ in spelling and membership (UPDATED_FIST/UPDATED_FIRST, UPDATE_LAST/UPDATED_LAST, and CONCAT). Treat exact validation as ambiguous until confirmed against the TAG runtime.
Known implementation delta at skill creation
The current TypeScript tokenizer/parser does not yet model all documented constructs. Notably absent or incomplete are LOG, FOR, IS_EMPTY, IS_NOT_EMPTY, case-insensitive spellings, structural ordering inside IF/WHILE, attribute validation beyond VAR type, and full expression parsing. Re-check source before relying on this list because it is expected to shrink as the linter evolves.