REA Introduction

REA template engine is the younger “sister” of the piecewise template engine NEA and it performs a completely different range of tasks. The main task of REA is to ensure both the processing of micro markup templates and ensuring their interactivity. The most striking example is the markup and liveliness of such templates for bots that can interact with chats in trading rooms. As a result, REA itself consists of a lexer and, directly, the main class responsible for converting templates, chat responses, etc. – into something more lively and interactive

How it's works?

Your bot need to use REA layouts in messages he send to your users. On users (client) side REA will transform this messages to interactive format (messages with buttons, inputs etc.). In same time your bot will need to process incoming user messages with commands (like message /hello-world) . All's simple and clear

To use REA you need to be Elite Trader on Symlix and have to understand how work with Symlix REST API

Get Started

REA language templates basicaly based on next concepts:

   - [!rea!] initialization meta tag (required for init REA for message)
   - [] Table blocks (reccomended to use for table-based layouts)
   - {} Objects (all interactivity based on it)
   - {} Containers ("objects" with child objects)
   - [*...*] Internal micromarkup for text

Example for tables on right sidebar (please don't copy text from here - it's just example):

                                
[ [.."row 1 content here"++] [.."row 2 content here"++] ]

                            

will create table with 2 rows. Cells count in row based on number of objects/containers included in a row. For example lets try to create working table with two rows and some empty objects:

Copy
                                
[ [{}{}{}] [{}] ]

                            

And you will see next result if you will look at HTML source code of message:

                                
<div class="rea-ui-table">
	<div class="rea-ui-row-3 rea-ui-row-el">
		<div class="rea-ui-object"></div>
		<div class="rea-ui-object"></div>
		<div class="rea-ui-object"></div>
	</div>
	<div class="rea-ui-row-1 rea-ui-row-el">
		<div class="rea-ui-object"></div>
	</div>
</div>

                            

Yes, result tables are not html <table>, but if we want to understand visual representation, we need to look table example bottom:

     
 

As we can see, there are 3 cells in first row and 1 in second - based on objects in rows. Now we know how to prepare layout for our messages, but we still need to understand what is objects and how it's works

Concepts

Copy
                                
[ [.."row 1 content here"++] [.."row 2 content here"++] ]
 
                            
Copy
                                
{{.."object 1 of external container"++}{.."object 2 of external container"++}}

                            
Copy
                                
{ BUTTON | "Say hello" | hello }

                            
Copy
                                
{ "My [*b*]super[*/b*] test with [*br*] newline and [* *] big [*b*]magic[*/b*]" }

                            

Real Examples

Copy
                                
[
[{"row1 col1"}{"row1 col2"}{"row1 col3"}{"row1 col4"}]
[{"row2 col1"}{"row2 col2"}]
[{"row3 col1"}]
[{"row4 col1"}{"row4 col2"}{"row4 col3"}]
]

                            

Result:
Copy
                                
[
[{"row1 col1"}{"row1 col2"}{"row1 col3"}]
[{{"row2 col1 obj1"}{"row2 col1 obj2"}}]
[{"row3 col1"}]
]

                            

Result:
Copy
                                
[ [{ BUTTON | "Say hello" | act_say_hello }] ]	

                            

Result:
Copy
                                
{"Please enter data:"}
[
[{"Your name:"}{ TEXTBOX | username | "Name" | userinfo_update }]
[{"City:"}{ TEXTBOX | city | "City" | userinfo_update }]
[{ SUBMIT | "Submit" | userinfo_update }]
]

                            

Result:

What is Objects?

Let's return to containers and their possible applications. Basicly container/object are empty and has form: {}, but we can type inside it some special tokens named attributes (it's a enumeration of some keywords, strings, numbers, identifiers etc) in strict order :

What's full list of supported tokens inside object body and how it's works?

   1) Identifiers - Most default type of tokens. They are represented as words without any types of quotes (used to create strings in objects) and spaces. For example test_id or helloworld123 are identifiers, but tokens writed as valid interger numbers are not identifiers

   2) keywords - In most cases it's represent type of object, writted in upper case and object starts from it. For example: BUTTON, LINK, COPY, WINDOW etc. All keywords also are identifiers

   3) Strings - This type represented as text data with quotes (" or ') as first and last characters of token. Objects consisted of only one string tokens (like {"Hello, world!"}) are string objects

   4) Integer numbers - This is rare type of tokens which represented as valid integer numbers. Floating numbers not supported

   5) Named attributes - Special type of attributes. It's like identifiers, but starts from @ character. Some of named attributes can need to be placed with string attribute next from it to describe value of named attribute. This attributes not required by any type of object

   6) Delimiters - This type used to split all attributes between each other. Typed as | character. It's supported to not use it, but it's very important for named attributes

     Example of described types in real object:
  

This example describe parts of real BUTTON object:

Copy
                                
[ [{ BUTTON | "Say hello" | act_say_hello | "val_say_hello" | @title "Say hello button" | @desktop }] ]

                            

But you need to remember, that arguments of objects readed based on type ond order. It's works as like that: first identefier (excluding keyword) here - are name of action for button. As result this mean:

Copy
                                
[ [{ BUTTON | act_say_hello | "Say hello" | "val_say_hello" | @title "Say hello button" | @desktop }] ]

                            

will be equal to previous example

Next sections of documentation will describe supported by REA types of objects and their use


String Objects

As described in "What is Objects?" section, simple objects with only one string arguments are string objects. This objecta can be used for create labels for inputs, some descriptions with styling etc

For styling strings and some attributes of objects like BUTTON, FRAME, SWITCH, SUBMIT etc there are special micromarkup tags listed here:

[*b*]Bold text[*/b*] Bold text
[*i*]Italic text[*/i*] Italic text
[*u*]Underline text[*/u*] Underline text
[*s*]Strikethrough text[*/s*] Strikethrough text
Text with[*br*]newline Text with
newline
Text with[*hr*]horisontal line Text with
horisontal line
Non-breaking[*nbsp*]space Non-breaking space
Non-breaking[* *]space with step (x1) Non-breaking space with step (x1)
Non-breaking[*       *]space with step (x7) Non-breaking       space with step (x7)
Empty cha[**]racter Empty character
Smile [*:smile:*]
Text with Font Awesome [*fa:check*] icon

String objects with any arguments like named arguments will be converted to extended string objects. This objects have more complicated HTML DOM structure (with additional container), but looks like normal string objects

Also STRING objects supports Special Tokens - additional formated non-static data like traderoom ID, current username etc. This tokens need to be typed in [*tokenname*] format in strings:

tradeid
Represent current traderoom ID
[!rea!]
{"Current traderoom have ID: [*tradeid*] - it's nice, isn't it? =)"}
currentuser
Represent username of user who now see this message. For example, if traderoom will be opened by bot owner (ExampleBot), then he will see ExampleBot as username, but buyer of bot will see his username
[!rea!]
{"Hello, [*currentuser*]"}
senderstatus
Represent current status of bot: online/away/offline
[!rea!]
{"Bot status: [*senderstatus*]"}

Examples

Copy
                                
{ "My [*b*]super[*/b*] test with [*br*] newline and[* *] big [*b*]ma[**]gic[*/b*]" }
 
                            

Result:
Copy
                                
{"Hello, look at [*u*]this[*/u*] smile: [*:evil:*] - it's working [*b*]fine[*/b*] [*:smile3:*]"}
 
                            

Result:
Copy
                                
{"0[* *]1[*  *]2[*   *]3[*    *]4[*     *]5"}
 
                            

Result:

Button Objects

BUTTON objects are objects for creating interactive buttons. When user press this buttons, then from his side there will be sent message with command (and value if specified)

Syntax:

Copy
                                
[ [{ BUTTON | "Button text" | action_name | "action_value" }] ]

                            

* "action_value" argument are optional

Let's look to example:

Copy
                                
[ [{ BUTTON | "Say hello" | act_say_hello | "val_say_hello" }] ]

                            

When user press button with text "Say hello", then there will be sent message to bot (form this user in chat):

                                /act_say_hello val_say_hello

                            

And your bot will be able to react to incoming massage to detect what's user pressed

If you don't use value argument, then bot will receive just /act_say_hello message

P.s. "Button text" argument supports strings micromarkup tags

Examples

Copy
                                
[!rea!]
[
    [
        {  BUTTON  |  "Say hello"  |  act_say_hello  |  "val_say_hello"  }  
    ]
]
 
                            

Result:
Copy
                                
[!rea!]
[
    [
        {  BUTTON  |  "Menu"  |  menu  }  
		{  BUTTON  |  "Back"  |  action | "-1" }  
		{  BUTTON  |  "Continue"  |  action | "1" } 
    ]
]
 
                            

Result:

Copy Objects

COPY objects are very simple type of objects which used to create buttons for copying data to clipboard

Syntax:

Copy
                                
{ COPY | "copied text data" | "Button Text" }

                            

* Last argument is not strictly required. By default button will be labeled with "Copy" text

After user press such button, copied text data will be saved to clipboard

Examples

Copy
                                
{ COPY | "my super data" | "Press me to copy" }
 
                            

Result:
Copy
                                
{"Current trade ID: #[*tradeid*]"}{"[*  *]"}{COPY | "#[*tradeid*]"}
 
                            

Result:

Image Objects

IMG are simple objects to use HTML img images in your messages

Syntax:

Copy
                                
{ IMG | "https://site.com/myimage.png" }

                            

Examples

Copy
                                
{ IMG | "https://symlix.com/templates/assets/img/nav-icon/btc.png" }
 
                            

Result:

Graph Objects

GRAPH are simple objects to create visual graphs from points list in your messages

Syntax:

Copy
                                
{ GRAPH | "[Array of points]" }

                            

Examples

Copy
                                
{ GRAPH | "[10, 21, 33.5, 16.2, 14.1, 9.4, 7, 5.2, 3, 6, 7.7, 14, 22, 35, 26, 20, 21]" }
 
                            

Result:

Timer Objects

TIMER are simple objects to automated visual countdown timers in your messages

Syntax:

Copy
                                
{ TIMER | "target_unix_timestamp_s" }

                            

or you can use integer number of seconds instead last string agrument (not recommended, but supported):

Copy
                                
{ TIMER | target_unix_timestamp_s }

                            

Examples

Copy
                                
{ TIMER | "1728306141" }
 
                            

Result:

* Please remember that timestamp from example - just example

Forms

Forms are special mechanisms which don't need manual initializaton. They appears when you use some of form-based objects like TEXTBOX, INPUT, SWITCH etc. Form behavior are very similar to form tag behavior from HTML: all inputs which related to same form can be submited by pressing submit button (here - SUBMIT object), but here inputs meed to be marked by argument which represent target form name

After submiting form bot will receive message from user like:

                                /form_name input1_name=value1&input2_name=value2&input3_name=value3

                            

As you can see, it's like commands with values for BUTTON objects, but value are key-value query string with & char as delimiter of pairs. All values are url-encoded (it mean that "hello world" value for test_input input will be sent as test_input=hello%20world )

For human-radable messages on client-side you need to place at start of form message $$hrdbl META object:

                                { META | $$hrdbl }

                            

If you try to use first example without $$hrdbl and try to fill form with data John / London and submit form, you'll see next:

But with $$hrdbl result will be:

User will se message in more human-readable form, but bot still will receive message in original form like in first example

Examples

Copy
                                
{ META | $$hrdbl }
{"Please enter your data:"}
[
[{"Your name:"}{ TEXTBOX | username | "Name" | userinfo_update }{}{}]
[{"Your city:"}{ TEXTBOX | city | "City" | userinfo_update }{}{}]
[{ SUBMIT | "Submit" | userinfo_update }]
]
 
                            

Result:
Copy
                                
{ META | $$hrdbl }
[
[{"Cats or dogs?"}
{ SWITCH | animal_type | "Cats" | "cats" | animal_voting }
{ SWITCH | animal_type | "Dogs" | "dogs" | animal_voting }
]
[{ SUBMIT | "Vote" | animal_voting }]
]
 
                            

Result:

Metadata Objects

META objects are by default invisible form-related objects like hidden HTML input

Syntax:

Copy
                                
{ META | par_name | "value" | form_name }

                            

But another main functions of META objects - been system-level metadata tags. Any system META tags have $$ chars at start of their par_name:

    1) Human-readable mode:

Copy
                                
{ META | $$hrdbl }

                            

This mode transform ugly-like messages with commands to more beautiful human-readable form

* Human-readable mode also lock BUTTON, SWITCH, INPUT, TEXTAREA etc objects in message after via them user sent command to bot. This can be disabled by using $$reusable system meta tag

    2) Reusable forms/buttons (unlock):

Copy
                                
{ META | $$reusable }

                            

    3) Hidden message:

Copy
                                
{ META | $$hidemsg }

                            

This mode hide full message from user, but it's may be very useful to use in pair with ACTION object to call some actions related, for example, with closing WINDOW/FRAME, or for change visibility of some messages

    4) Change [BOT] label:

Copy
                                
{ META | $$labeltext | "label_type" }

                            

Your bot can change [BOT] label text to some another if you set as "label_type" string any item from supported list: none, bot, info, instruction, instructions, auto, important, warning, details, payment details, payment info, result, rules, success, error

Switch Objects

SWITCH objects are special type of objects used in forms

This kind of objects are very similar to "radio" selectors. From one of SWITCH selectors group can be selected only single item

Syntax:

Copy
                                
{ SWITCH | par_name | "Swicth button text" | "value" | form_name }

                            

par_name determine "group" and real parameter name we need to select. Let's look to example:

Copy
                                
[
[{"Cats or dogs?"}
{ SWITCH | animal_type | "Cats" | "cats" | animal_voting }
{ SWITCH | animal_type | "Dogs" | "dogs" | animal_voting }
]
[{ SUBMIT | "Vote" | animal_voting }]
]

                            

As we can see, there are animal_type group for switch selectors and it is - one of parameters which would be sent after form submitting as animal_voting action (such as virtual form name). For example if you'll select "Dogs", there will be next message from client to bot:

Copy
                                
/animal_voting animal_type=dogs

                            

One message can support multiplie switch selectors and virtual forms - all of them splited by their par_name/form_name attributes (but it cannot be used with { META | $$hrdbl } meta tag or without { META | $$reusable } meta tag due to automated lock on submitted form)

Examples

Copy
                                
[
[{"Do you like this voting?"}]
[
{ SWITCH | rate | "Yes [*:smile:*]" | "1" | voting_feedback }
{ SWITCH | rate| "No [*:angry:*]" | "2" | voting_feedback }
{ SWITCH | rate | "I don't know [*:shock:*]" | "3" | voting_feedback }
]
[{ SUBMIT | "Review voting [*fa:check*]" | voting_feedback }]
]
 
                            

Result:

Textbox/Input Objects

TEXTBOX (alias: INPUT) objects are special type of objects used in forms

Default TEXTBOXs are inputboxes for text data - it's a reason why TEXTBOX and INPUT is the same type of objects, but it's better to use TEXTBOX identifier to split any advanced controls from simple textboxes

Syntax:

Copy
                                
{ TEXTBOX | par_name | "Placeholder" | form_name }

                            

or without placeholder:

Copy
                                
{ TEXTBOX | par_name | form_name }

                            

If we add additional identifier argument to this examples, we'll receive way to change input type. For this case more good choice to use INPUT alias instead TEXTBOX and result would be like:

Copy
                                
{ INPUT | par_name | "Placeholder" | form_name | input_type }

                            

or without placeholder:

Copy
                                
{ INPUT | par_name | form_name | input_type }

                            

Supported input types: number, date, month, week, time, email, color

Named Attributes

Named attributes are special kind of attributes described in What is Objects? section. Currently there are supported named attributes:

@title "Element title" Set title HTML attribute of object
Supported by all visible objects
@class "myclass" Add additional CSS class to object based by next scheme:
rea-ui-custom-frame-myclass
Where frame - type of object in lowercase, myclass - name of class in value of named attribute
@confirm Ask confirmation before doing action
Supported by LINK, BUTTON, SUBMIT objects
@inspect or @inspect "my-cmd"
@mobile Display object only on mobile devices
@desktop Display object only on desktop devices
@:specialtoken "value" Use Special Token and value to decide - show object or not

Frames and Windows

FRAME and WINDOW - complicated objects which gain bot ability to open internal popups (or real popup browser windows) with resource located on remote web address

Syntax of FRAME:

                                
{ FRAME | "Open popup link text" | frame_unique_name | "https://frameurl.com" | "Frame text description (can be saw near frame inside popup)" }

                            

Let's try to create such FRAME via:

                                
[!rea!]
{ FRAME | "Open wikipedia in frame" | test_frame_wiki__1| "https://wikipedia.org" | "Super test description [*br*] Anotherline text with [*b*]important[*/b*] information [*br*] and [*i*]last[*/i*] line" }

                            

As result user will see link:

And after this user click that link he will see popup:


IMPORTANT: frame name must be unique and associaced only with single frame. In one trade chat must be only single FRAME object with, for example, frame_unique_name from previous example. If you force closed popup via closepopup (closewindow) ACTION (with "disablelink" argument) and want again gain user access to such popup, you need to generate new frame name!

Syntax of WINDOW:

                                
{ WINDOW | "Open window link text" | window_unique_name | "https://windowurl.com" }

                            

As you can see, there is no descriptions for WINDOW objects. It's work similar to FRAME, but instead opening popup, there wil bee window


FRAME/WINDOW objects can be manipulated via special ACTION objects. You can force close it, change url, disable link for opening etc

Also FRAME/WINDOW objects can be inspected via @inspect named attribute

Action Objects

ACTION objects are special objects which can do some background actions on client-side: closing popups, windows, toggling visibility of messages etc. This kind of objects can contain action name (type) and endless count of data string attributes

Syntax:

Copy
                                
{ ACTION | action_name | "action_data_0" | "action_data_1" | . . . | "action_data_N" }

                            

Currently there are next list of supported types of actions:

Actions with Frames:

    1) closepopup - closing FRAME popups

Short form (just closing popup without disabling frame link):

Copy
                                
{ ACTION | closepopup | "frame_unique_name" }

                            

Extended form (closing popup with formatted disabling frame link):

Copy
                                
{ ACTION | closepopup | "frame_unique_name" | "disablelink" | "status_type" | "fontawesome_v4_icon" | "New text of disabled link" }

                            

* All string arguments backward from and to start are not strictly required and also can be empty strings

    2) disablepopup - more simple variant of previous action. Can disable frame links without closing opened popups

Syntax:

Copy
                                
{ ACTION | disablepopup | "frame_unique_name" | "status_type" | "fontawesome_v4_icon" | "New text of disabled link" }

                            


    3) changeframeurl - change url of FRAME popups

Copy
                                
{ ACTION | changeframeurl | "frame_unique_name" | "http://newurladdress.com" }

                            


    4) disableframemsg - can disable first frame link in message if we know message ID

Copy
                                
{ ACTION | disableframemsg | "123456" | "status_type" | "fontawesome_v4_icon" | "New text of disabled link" }

                            


Important to note that "status_type" argument value currently can be only "success", "fail" and "default". FA icons for example: "check" and "times"

Let's try to disable popup and link for frame for example from FRAME section of documentation. We just need to send message to client and use unique frame name from example (test_frame_wiki__1):

Copy
                                
{ META | $$hidemsg }
{ ACTION | closepopup | "test_frame_wiki__1" | "disablelink" | "fail" | "times" | "You entered incorrect data" }

                            

As result, if popup was opened, it will be closed and link:

Will change to this:

Due to $$hidemsg meta-tag on client-side there will be no any messages and user won't see anything another than result of action

Actions with Windows:

    1) closewindow - closing WINDOW windows

Extended form:

Copy
                                
{ ACTION | closewindow | "frame_unique_name" | "disablelink" | "status_type" | "fontawesome_v4_icon" | "New text of disabled link" }

                            

closewindow action syntax are identical to closepopup, but with different action name as first argument

Actions with Messages:

    1) hidemsg - hide message in chat by message ID

Copy
                                
{ ACTION | hidemsg | "123456" }

                            

    2) showmsg - turn hidden message to be visible again

Copy
                                
{ ACTION | showmsg | "123456" }

                            

Using REA without bot

If you have no bot, you still can use some of feautures of REA in your trade instructions auto message. For example you still can use Special Tokens like traderoom ID, COPY buttons, LINKs etc

REA scheme of work

This diagram represent scheme of work bots using REA: