⟡ hearthere ⟢
  • Quick start
  • Install MIT
  • Install PRO
  • Updating
  • Optimization
  • Update v4-v6
  • Backups
  • Console utility bin/totum
  • Basics for users
  • Interface and Layout
  • Tables and their parameters
  • Prefilter
  • Fields and their parameters
  • Syntax
  • General information
  • Code Application Points
  • Return of the code execution result
  • Addresses
  • Reference to Values
  • Addressing Line Values Within Code
  • Addressing Field Values
  • Addressing the Previous Value
  • Addressing the Display for Selects
  • Getting Values of Pinned Fields
  • Define Field Name by Code
  • Nesting Level for Select-Tree
  • Shorter Reference
  • Addressing a List Item
  • Addressing a List Section (Column)
  • Functions
  • Function Call in Code
  • Function Autocomplete
  • Hotkeys
  • Variables
  • Variables inside the code
  • Global and Process Variables
  • Global Variables
  • Process Variables
  • Passing Variables into a Code String
  • Calculation order
  • Code Line Calculation Sequence
  • Sequence of Mathematical Operations in a String
  • MATH β€” mathematical order
  • Types
  • Data Types
  • Types of Data Storage
  • Operators
  • Comparison Operators
  • Mathematical Operators
  • Other
  • Logical construct cond
  • String Concatenation
  • Text Inclusion in Code
  • QROW in where-parameters
  • Code, actions, formatting
  • Relational relationships
  • Calculation order and calculation units
  • Auto-complete calculations and timing
  • Duplicate rows and cycles
  • Comparisons
  • Functions
  • Debugging
  • Print and CSV
  • API
  • Roles and users
  • Notifications
  • Scheduled Actions
  • System tables
  • Trees
  • Anonymous tables
  • External Forms
  • Exporting and importing tables
  • [PRO] MeiliSearch
  • [PRO] Databases
  • [PRO] Custom CSS
  • [PRO] Custom docs
  • [PRO] LDAP AD
  • [PRO] File versions
  • [PRO] List-unsubscribe
  • [PRO] Dynamic fields
  • [PRO] Only Office
  • [PRO] Auth Tokens
  • [PRO] 2FA
  • [PRO] Superlang
  • [PRO] Daemons
  • [PRO] Profiler
  • Connecting functions
  • [SRV] Installation and Connection
  • [SRV] Export, PDF, Upload, and Preview
  • [SRV] XLSX/DOCX Generators
  • Syntax

    General information

    Code Application Points

    The code is used for calculating field values, performing actions, and determining the formatting of fields, rows, and tables.

    Codes are also used when duplicating rows and invoking panels in selects.

    The code can be stored as text in a field and be called during the execution of other code by passing the necessary parameters to it using the exec function.

    Return of the code execution result

    The code is processed line by line, and the value is returned from the line starting with =: regardless of its position.

    =: 10 + 10
    
    // Result: 20
    

    Addresses

    Reference to Values

    • $ β€” a line of code.

    • # β€” a cell value.

    • $# β€” a variable within the code.

    • #$ β€” a cell value defined by the code.

    • $$ β€” calls a line of code defined by another code. An elegant way of branching!

    • @ β€” reference to non-string fields in other tables.

    Addressing Line Values Within Code

    Addressing a line value in the code is done through $codename.

    Naming a line is done as codename:. Line names are case-sensitive and can consist of Latin letters, digits, and underscores.

    To visually indicate the order of code line calls or hierarchy, you can use tabs. Single-line comments starting with // are also supported.

    = : $code1 + $code2
        // Comment
        code1: 10
        code2: 10
    
    // Result: 20
    

    Addressing Field Values

    Addressing the value of a field in the current table is done through #fieldname. The value of the fields is taken at the moment the code execution starts.

    Addressing fields in another table is done through functions like select.

    If the code execution is in a field of the table's row part, and the value is taken from a field of the row part, then the value is taken from the current row.

    Addressing the Previous Value

    When making changes to a field, it is possible to address the previous value through #old.fieldname. This works in codes and action codes.

    • At the moment of creating a row or table, #old.fieldname equals null.

    The previous value is the value with which the field entered the current recalculation cycle according to the recalculation unit.

    Addressing the Display for Selects

    Addressing the displayed value, rather than the base of the field for select and select-tree, is done through #s.fieldname.

    Getting Values of Pinned Fields

    It is possible to get the pin status of a value for fields with codes β€” true or false using #h.fieldname.

    For pinned fields, you can get the calculated value through #c.fieldname.

    Define Field Name by Code

    It is possible to address a field defined by a code string using #$whatfield. Thus, the value in the whatfield: string will determine the name of the field from which to take the data.

    Nesting Level for Select-Tree

    Addressing #l.name_field can be used for any field in the select-tree β€” returns the nesting level of the value in the field.

    More about tree-view ⟢

    id fieldname1 fieldname2
    1 10 (C=5) [HAND] 15
    example1: #fieldname1 + #fieldname2
    
    // Result: 25
    
    example2: #h.fieldname1
    
    // Result: true
    
    example3: #c.fieldname1
    
    // Result: 5
    
    example4: #$whatfield
    
        whatfield: "fieldname2"
    
    // Result: 10
    

    Shorter Reference

    To refer to non-row fields in another table, a shorter reference @tablename.header_or_footer_fieldname is used.

    @ is a shorthand for select. @ will not be taken at the start of code execution like #field_name, but will be taken in its turn.

    If the reference is to the row part of the table, the following notations are used:

    • @table.field[#value] is equivalent to:

      =: select(table: 'table'; field: 'field'; where: 'id' = #value)
      
      
    • @table.field[[#value]] is equivalent to:

      =: selectList(table: 'table'; field: 'field'; where: 'id' = #value)
      
      
    • @table.field.where[#value] is equivalent to:

      =: select(table: 'table'; field: 'field'; where: 'where' = #value)
      
      
    • @table.field.where[[#value]] is equivalent to:

      =: selectList(table: 'table'; field: 'field'; where: 'where' = #value)
      
      

    Such references can be used within functions:


    =:
    select(table: 'table'; cycle: @cycles.id.status[#status]; field: 'field')

    Addressing a List Item

    Addressing $list[1], #listfieldname[1], $list[$#iterator] or $list[$codename] will return the value of the list item similarly to the listitem function.

    The number or key of the list item inside square brackets can be specified in all possible ways.

    If there is no element with the requested key, the expression will return null.

    If the structure you are addressing contains technical symbols or non-Latin characters, the path inside the brackets must be enclosed in quotes!

    $list["ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²Π»Π΅Π½ΠΈΠ΅"], #listfieldname["Бсылка"], $list["date.settings"] or $list["so$iska"]

    // Using the function:
    example1: listitem(list: $list1; item: 1)
    
    list1: listcreate(item: "A"; item: "B"; item: "C") 
    
    // Result: "B"
    
    // Using quick call:
    example2: $list2[1]
    
    list2: listcreate(item: "A"; item: "B"; item: "C") 
    
    // Result: "B"
    

    Similarly, you can address nested elements at any depth:

    id fieldname3
    1 ["b", "c"]
    example3: strAdd(str: $code3_1[0]; str: #fieldname3[1]; str: $code3_2[test])
    
     code3_1: listCreate(item: "a"; item: "b")
     code3_2: rowCreate(field: "test" = "z")
    
    // Result: "acz"
    
    example4: $code4[0][test]
    
     code4: listCreate(item: $row4)
        row4: rowCreate(field: "test" = "abc")
    
    // Result: "abc"
    

    Addressing a List Section (Column)

    Addressing a section works similarly. If you need to get a list by key from a list of associative arrays, in addition to the listSection function, you can use the syntactic notation $row[[key]], #rowfieldname[[key]], $row[[$#key]] or $row[[$key]].

    example5: $listList[[1]]
        listList: listCreate(item: $l1; item: $l2)
            l1: listCreate(item: 1; item: 2; item: 3)
            l2: listCreate(item: 4; item: 5; item: 6)
    
    // Result: [2,5]
    

    Functions

    Function Call in Code

    Parentheses are a sign of a function.

    Function parameters can be defined in any order. In some cases, the order of parameters within the function determines the result it returns.

    A good practice is to place the function parameters in the order they are specified in the function's autocomplete, as well as to maintain proper spacing.

    ALL FUNCTION PARAMETERS MUST BE FILLED. IF A PARAMETER IS NOT USED, IT MUST BE REMOVED!

    tablename

    id fieldname1 fieldname2
    1 10 10

    example1: select(table: 'tablename'; field: 'fieldname1'; where: 'id' = 1)
    
    // Result: 10
    
    • Yellow β€” indicates name-parameters to which name of fields or tables (depending on the parameter) are passed. The name can be passed in any way. If it is specified manually, then when typed in single quotes '', the name search mechanism in the current database schema will be triggered.

    • Bold β€” indicates mandatory function parameters.

    • Underlined β€” indicates multiple parameters that can be specified in the function call several times. The order of the call is important, as selections and sorts will be applied in the order they are specified in the function call.

    A FUNCTION CANNOT BE CALLED INSIDE ANOTHER FUNCTION β€” THIS IS DONE THROUGH A SEPARATE LINE!

    example2: select(table: 'tablename'; field: 'fieldname1'; where: 'price' = $what_id)
    
        what_id: round(num: #price; type: "up"; step: 1; dectimal: 0)
    
    // Result: 10
    

    Function Autocomplete

    • When typing a function, it is searched in the function database.

    • When placing a parenthesis ( or ) after the function name, it is automatically filled.

    • When placing ; and starting to type the next parameter, available parameters are searched.

    • When typing names in single quotes '', the field in the source table is searched.

    • When placing a forward slash / or ; instead of an opening parenthesis, the parameter is searched. The subsequent parameter is also searched through / or ;. At the end of typing, when placing a parenthesis ( or ), the syntax is automatically replaced with valid syntax.

    Hotkeys

    • TAB β€” moves to the next function parameter.

    • SHIFT + TAB β€” if the cursor is before the closing ;, the next parameter up to the closing ; will be selected.

    • SHIFT + TAB β€” if the cursor is anywhere else in the parameter, the current parameter including ; will be selected.

    • For Mac, the equivalent hotkey is OPT+TAB.

    Variables

    Variables inside the code

    Such variables exist only during the execution of specific code within one iteration of computation.

    These variables can be defined by certain functions, such as var or while.

    To refer to them, use $#paramname.

    There is a list of reserved variables that return specific values:

    • $#ntn β€” returns the name of the current table.

    • $#nci β€” returns the number of the current cycle.

    • $#nth β€” returns the hash of the current table. (only for temporary tables).

    • $#lc β€” returns an empty list.

    • $#nd β€” returns the current date in Y-m-d.

      example2: dateAdd(date: $#nd; days: 10; format: "Y-m-d")
      
      // Result: "2019-08-10"
      
    • $#ndt β€” returns the current date in Y-m-d H:i.

    • $#ndts β€” returns the current time with seconds Y-m-d H:i:s.

    • $#nu β€” returns the id of the current user.

    • $#nr β€” returns a list of ids of the current user's roles.

    • $#nfv β€” returns the value of the current field (not applicable in the code section).

    • $#onfv β€” returns the previous value of the current field.

    • $#ids β€” returns a list of id of rows selected with checkboxes (available only in Button action code).

    • $#nh β€” returns the current host.

    • $#nf β€” returns the name of the current field.

    • $#nti β€” returns the id of the current table.

    • $#nl β€” returns a special newline character.

    • $#duplicatedId β€” returns the id of the row from which duplication was performed (only for the CODE section when adding in the inserted row during duplication). Otherwise, returns 0.

    • $#ih β€” available only in the addition row. Allows passing the hash of the addition row to a temporary table and then returning data to the field of the addition row using the hash parameter of the set function. Or perform set in the addition row field without calling the temporary table. Used in the addition row in conjunction with the field parameter buttonActiveOnInsert.

    • $#rows β€” available only in formatting code and in charts code β€” returns a rowlist with the contents of the rows displayed on the page.

    • $#changes β€” a variable available only in table action code. Information about changed fields in the table in the form of a row:

      • deleted β€” id of deleted rows.
      • restored β€” id of restored rows.
      • added β€” id of added rows.
      • changed β€” row with keys being the id of changed rows and values being a list of name of fields changed in the row.
      • reorderedIds β€” id of rows with changed order by n.

      Example of getting a list of id of rows where a change occurred in the field_1 field:

      =: rowKeys(row: $listf)
              listf: listFilter(list: $#changes[changed]; key: "value" = "field_1")
      

      Format of changes:

      {
      "deleted": [],
      "restored": [],
      "added": [],
      "changed": {
          "305": [
              "some_field_in_row"
              ],
          "params": [
              "f_column_footer"
              ]
          },
      "reorderedIds": []
      }
      
    • $#slPro β€” only in PRO. A variable available only in Button action code similar to $#ids. Gets fields selected with the mouse similar to the structure of $#changes.

    • $#kanban β€” available only in panel-view in kanban mode when executing h_kanban_html_code.

    • Variables in the code can be created by functions:

    example1: while(action: $set; limit: 10)
        set: var(name: "count"; value: $plus; default: 0)
            plus: $#count + 1
    
    // Result: 10
    

    Global and Process Variables

    Global Variables

    A global variable can be written using the globVar function.

    It is accessible from any code.

    It is called β€” @$name_glob_var

    When requesting a variable through globVar, a request lock can be set for use in concurrent processes that check and change the variable's value.

    For example, if false, then set to true and upon process completion change back to false. If true, do nothing. During the check and write of true, a competing process might intervene and write true, thus two processes will execute, although the second should have been rejected.

    To avoid this, a lock is set when requesting the value, which is released after the specified time, or when writing the variable or requesting its value with block: false.

    The read lock works only for requests that set or release the lock through the block parameter. When obtaining the variable @$name_glob_var, its value will be returned immediately.

    The variable is written immediately outside the transactional model!

    Writing outside the transactional model can lead to the variable sticking in cases where the process started and the variable was set, but then the transaction was rolled back.

    It is recommended to use it together with tryCatch β€” in this case, in catch, the variable is reset or set to the initial value, which will occur if the transaction is canceled.

    Process Variables

    A process variable can be written using the procVar function.

    It is accessible from any code.

    It is called β€” $@name_proc_var.

    It exists only within a single php process.

    When closing the iframe using the Buttons Close after execution parameter, the process ends and a refresh of the table in the window below occurs. Since this is a new process, when executing the table formatting codes in the lower window, the previously set variable will be empty!

    Passing Variables into a Code String

    Using the $codename{var: "varname" = value} construct, you can pass the value of the variable varname into the codename string and further.

    varname can also be set by code.

    example1: strAdd(str: $code1{var: "fruit" = "apple"}; str: " and "; str: $code1{var: "fruit" = "banana"})
        code1: strAdd(str: "green "; str: $#fruit)
    
    // Result: "green apple and green banana"
    

    In this way, you can process array elements:

    example2: $split{var: "fruits" = $code2}
    
     split: if(condition: $#fruits != $#lc; then: $str1; else: "")
        str1: strAdd(str: $#fruits[0]; str: ", "; str: $split{var: "fruits" = $fruitsCut})
            fruitsCut: listCut(list: $#fruits; cut: "first"; num: 1)
    
    code2: listCreate(item: "apple"; item: "banana"; item: "lemon")
    
    // Result: "apple, banana, lemon, "
    // This example is provided here as an example; this specific operation is performed by the listJoin() function.
    

    You can pass multiple variables using ; β€” $code1{var: "fruit" = "apple"; var: "type" = "2"}

    Calculation order

    Code Line Calculation Sequence

    Calculations are performed from the = : section in a cascading manner, referencing the values of other lines from left to right.

    If a line is referenced multiple times, it will be calculated as many times as it is referenced.

    1.| = : $code1 + $code2 + $code2
    
    2.| code1: 10 / 2
    3.| code2: 10 * 2
    
    // Result: 45
    // Number of calculations:
    // Line 1 β€” 1 time
    // Line 2 β€” 1 time
    // Line 3 β€” 2 times
    

    When referencing a code line value with codename:, it is calculated each time it is referenced.

    To calculate a value only once and reduce the required processor resources, use ~codename:.

    tablename h_fieldname = 1

    example2: while(action: $set2; limit: 10)
    set2: var(name: "count"; value: $plus2; default: 0)
    plus2: $#count + $step2
    ~step2: select(table: 'tablename'; field: 'h_fieldname')
    
    // Result 10
    // Line step2: will be calculated only once at the first reference.
    // Without ~ before step2: select() would be executed 10 times.
    

    You don't need to economize on references to field values #fieldname, as they are the fastest.

    Be careful when using ~ in cyclic calculations, as you might mistakenly fix the result of the first cycle's calculation.

    Sequence of Mathematical Operations in a String

    In Totum, mathematical operations are performed in the sequence of their recording from left to right. Parentheses are not considered as they belong to functions.

    ATTENTION: by default, the order of execution differs from the accepted mathematical notation! Parentheses for mathematical operations are not used as they are a sign of functions.

    example1: 10 + 10 / 2
    
    // Result: 10
    
    // The code to implement the mathematical notation (32 + 10) / 2 = 21 would look like this:
    
    example2: $sum / 2
        sum: 32 + 10
    
    // Result: 21
    

    MATH β€” mathematical order

    To perform calculations as accepted in mathematics, the following notation is used:


    example3:
    math`$A3 + $B3 / 2` A3: 10 B3: 10 // Result: 15

    math can also be used inside functions:


    example4:
    if(condition: math`$A4 + $B4 / 2` = 15; then: true; else: false) A4: 10 B4: 10 // Result: true

    MATH processes parentheses as part of the mathematical formula:

    example5: math`2 / ($A5 + $B5)`
    
    A5: 10
    B5: 10
    
    // Result: 0.1
    

    Types

    Data Types

    • 5 β€” an integer or a decimal number. The decimal separator in codes is . (dot). When entering, you can use , in the field β€” upon saving, the comma will be converted to a dot.

    • "str" β€” utf-8 string value, it is advisable not to rely on large values, as it is fully transmitted to the web interface. When filled through the interface, it does not contain line breaks.

    • true, false β€” boolean values.

    • 'name' β€” name-parameter. Similar to a string, used in code with single quotes, which trigger autocomplete suggestions.

    • "" β€” an empty string or null.

    • null β€” an empty value. Cannot be entered manually, but can be the result of some functions and fields.

    • [] β€” an empty list. It is the result of functions, some fields, and the quick variable $#lc.

    Types of Data Storage

    • Single Value β€” the simplest type of storage.

      • For example:

        "mouse" or 5 or true or false
        
    • List of Values β€” an ordered list of values with numerical keys.

      • A table with one column and several rows, each row having a number.
      • Keys start from 0 with a step of 1.
      • For example:

        [1,2,3,4,5]
        
    • Associative Array β€” an object in the form of key-value pairs.

      • One row from a table with several columns.
      • For example:

        {"data":"String intervals","type":"Type","version":"Version 1"}
        
    • List of Associative Arrays β€” a list of objects in the form of key-value pairs.

      • A table with several rows and several columns.
      • Rows are numbered from 0 with a step of 1.
      • Columns are designated by alphanumeric keys.
      • For example:

        [{"data":null,"type":"Calculated in tree"},{"data": null,"type": "Calculated in loop"}]
        

    Operators

    Comparison Operators

    There is a separate documentation section on the results of comparisons!

    Mathematical Operators

    • + β€” addition.

    • - β€” subtraction.

    • * β€” multiplication.

    • / β€” division.

    • ^ β€” exponentiation.

    Other

    Logical construct cond

    cond: cond`($A=1 && $B=1) || ($A=2 && $B=2)`
    A: "..."
    B: "..."
    

    Returns true or false.

    • && β€” and.

    • || β€” or.

    Parentheses β€” grouping. The example above reads as: "If A=1 and B=1 or A=2 and B=2 then true."

    Can be used inside functions:

    cond_2: if(condition: cond`$line_1 != 0 || $line_2 != 0`; then: 100; else: 0)
    
    line_1: 10
    line_2: 0
    
    // Result = 100.
    

    String Concatenation

    Concatenation is performed using the strAdd function or the str sugar:

    str: str`"#" + $#nfv ++ "β€”" ++ #field`
    
    // Result: #34 β€” closed
    
    
    • + β€” concatenates without a space.
    • ++ β€” concatenates adding a space.

    Text Inclusion in Code

    If you need to include a part of text with line breaks in the code, you can do it this way:

    =: $text_in_code
    
    ```text_in_code:text
    Some text in this section.
    
    With automatic lines separators.
    ```
    
    

    If you want this section to be highlighted as totum-code, you need to specify it like this:

    =: $code
    
    ```code:totum
    =: set(table: 'table_name'; field: 'field_name' = $some_value)
    
    some_value: 10
    ```
    
    

    Variables inside this code block and row names will not overlap with variables and rows in the host code.

    QROW in where-parameters

    In the where parameters of functions, a special qrow construct can be used, which allows specifying various search conditions for the database.

    =: select(table: $#ntn; field: 'id'; where: qrow`'field_1' > 100 || 'field_2' = true`)
    

    qrow supports the following operators:

    • && β€” AND

    • || β€” OR

    • () β€” grouping

    Comparison operators are similar to those in the rest of the system.

    Name-parameters are specified in single quotes 'field_1'.

    In the comparison 'field_1' > 100, one name-parameter must be used.

    Name-parameters can be used on both sides of the comparison 'field_1' > 'field_2' β€” select rows where field_1 > field_2.

    Example with grouping:

    =: select(table: $#ntn; field: 'id'; where: qrow`'(field_1' > 100 && 'field_3' = true) || 'field_2' = true`)
    
    // field_1 is greater than 100 and field_3 is true or field_2 is true
    
    

    At the same level, operators must be the same!

    This is an erroneous example:

    =: select(table: $#ntn; field: 'id'; where: qrow`'(field_1' > 100 && 'field_3' = true) || 'field_2' = true && filed_4 = false`)
    
    // Result ERROR! because at the top level both || and && are used
    
    

    The correct way would be:

    =: select(table: $#ntn; field: 'id'; where: qrow`'((field_1' > 100 && 'field_3' = true) || 'field_2' = true) && filed_4 = false`)
    
    // (field_1 is greater than 100 and field_3 is true or field_2 is true) and filed_4 is false
    
    

    Multiple where can still be used, they work in AND mode:

    =: select(table: $#ntn; field: 'id'; where: qrow`'(field_1' > 100 && 'field_3' = true) || 'field_2' = true`; where: 'filed_4' = false)
    
    // (field_1 is greater than 100 and field_3 is true or field_2 is true) and filed_4 is false
    
    

    IMPORTANT!

    If you use id in comparisons in AND mode, the query will execute much faster if you place this condition in a separate where first:

    =: select(table: $#ntn; field: 'id'; where: 'id' != #id; where: qrow`'(field_1' > 100 && 'field_3' = true) || 'field_2' = true`)
    
    // id is not equal to the current row id and (field_1 is greater than 100 and field_3 is true or field_2 is true)