Style Guide

The purpose of this Style Guide is to provide a recommended style to write Extended code. Following a style guide ensures that any code written is consistent and readable. You want users to concentrate on what the code is doing, not how it’s written. Benefits include:

  • Users (including your future self!) will have a much easier time reading it and understanding it.

  • Users can quickly make educated guesses or assumptions on the purpose of the code

  • Code can be edited faster, and copied with minimal reformatting

  • Less work and thinking when switching between multiple projects

  • More aesthetically pleasing!

Indentation

Indentations should consist primarily of hanging indents, and occasionally vertically-aligned indentation.

Hanging Indent

All lines after the first line are indented. A tab or 4 spaces can be used.

SELECT Kpi FROM this.object
    WHERE <condition1>
    AND <condition2>
    AND <condition3>
Vertically Aligned Indentation

All lines after the first line are aligned with opening delimiter, or by opening dot notation

myList.filter(<condition1>)
      .filter(<condition2>)
      .as(<expression>)
      .sort(<property>)

Indentation - addRow and addColumn

When chaining multiple addRow or addColumn to a table.

// addColumn (Hanging indent)
myTable
    .addColumn("Col 1", 1)
    .addColumn("Col 2", 2)
    .addColumn("Col 3", 3)

Indentation - calculate

The code within a long calculate should be indented.

// Long calculate (Hanging Indent)
this.object.calculate(
    <code>
)

Indentation - forEach Loops

The code within a forEach loop should be indented.

// forEach loop (Hanging Indent)
myList.forEach(item:
    <code>
)

Indentation - IF Statement

The code within IF-THEN-ELSE blocks should be indented.

// IF Statement (Hanging Indent)
IF var1 > var2 THEN
    <code>
ELSE
    <code>
ENDIF

Indentation - Long Method Chains

When writing a Token Expression using many chained methods, indentation and new lines should be used. Each method after the first should appear on a new, indented line.

// Long method chains (Vertically Aligned Indentation)
myList.filter(<condition1>)
      .filter(<condition2>)
      .as(<expression>)
      .sort(<property>)

Indentation - Long Queries

Long queries with many conditions should have one indented condition per line.

// Long query (Hanging Indent)
SELECT Kpi FROM this.object
    WHERE <condition1>
    AND <condition2>
    AND <condition3>

Indentation - Methods with Many Arguments

Methods with many arguments should have each argument broken onto a new, indented line.

myTable := createtable(
    "ID",
    "Name",
    "Description",
    "Responsible",
    "Measure Owner",
    "Frequency",
    "Actual",
    "Target",
    "Actual YTD",
    "Target YTD",
    "Status",
    "Trend"
)

Blank Lines

Blank lines should be used to logically group, or separate, portions of the code. In the code below, the blank lines clearly differentiate the tasks of: creating an empty table, querying a list of objects, and then adding the objects in the list to the table.

myTable := createtable("ID", "Name", "Year ID")         // #1 Create the empty table

myKpis := SELECT Kpi FROM this.object                   // #2 Query for objets to populate the table

myKpis.forEach(kp:                                      // #3 Loop through the list of objects to add them to the table
    yearID := kp.id + "_" + this.bop.year
    myTable.addRow(kp, id, name, yearID)
)

Whitespace

Operators

A space should be used to separate an operator and its operands

var := "Hello"

true AND false
true OR false

5 + 5
5 - 3
5 * 2
5 / 2
5 % 4

10 > 8
8 < 9
10 >= 8
8 <= 9
5 = 5
4 != 3

myList CONTAINS t.100

After Commas

A space should be used after a comma when delimiting values

LIST(1, 2, 3, 4, 5)

createtable("ID", "Name", "Description")

calculate(actual, BOP, EOP)

SELECT Kpi, Indicator

Naming Conventions

Variables

Variable names should provide some indication of the contents of the variable. Names should be written in camelCase where the first letter of every word is capitalized, except for the first word. Avoid using names that will conflict with reserved words in Extended or with property IDs.

// Bad
x := this.object.actual
var := this.object.name

// Good
revenue := this.object.actual
objName := this.object.name

Extended Expressions

Extended Expressions should be given IDs that describe what the expression returns. These IDs should be written in camelCase where the first letter of everyword is capitalized, except for the first word. Avoid using IDs that will conflict with reserved words in Extended or with property IDs.

// Bad
t.503789.expression

// Good
t.getRedKpisFromObject.expression

Properties

Properties should be given IDs that describe the value of the property. These IDs should be written in camelCase where the first letter of everyword is capitalized, except for the first word. Avoid using IDs that will conflict with reserved words in Extended or with the IDs of system properties.

// Bad
this.object.500

// Good
this.object.dataDefinition

String Quotation Marks

Extended supports using single quotes '' and double quotes "" for writing Strings. Either type is fine, but avoid combining them.

Comments

It never hurts to add comments, but they should always be added to longer Extended code, or to code with more complex logic. In the scenarios above, there should be a comment (typically multi-line) that precedes the script and gives a general explanation of what it does. Afterwards, there should be comments within the script that explain smaller pieces of it.

Queries

Keywords SELECT, FROM, WHERE should be written in all upper case letters.

Longer queries with multiple conditions should be broken onto a new line after the FROM clause. The subsequent lines should be indented using hanging indents, and should have one condition per line.

SELECT Organisation FROM root.Organisation
    WHERE name = "*Unit*"
    AND orgType = "Division"
    AND start > BOY