Types

Scriggo implements all types of Go but only the most common types are documented here.

All values in Scriggo have a type and there are several basic types.

bool

Boolean values are the true and false values. These are examples of boolean variable declarations:

{% var a bool %}     a is false
{% var b = true %}   b is true
{% c := false %}     c is false

string

Strings are written with double quotes, as "hello", or with a grave accent, as `hello`. These are examples of string variable declarations:

{% var a string %}     a is an empty string
{% var b = "hello" %}  b is the string "hello"
{% c := "world" %}     c is the string "world"

To read the length in bytes of a string use the len function, instead to read the length in characters use the runeCount function. The name of the runeCount function comes from "rune" which is the term used in Go to name the characters. For a more accurate explanation you can read Strings, bytes, runes and characters in Go.

html

The html type is a string type representing HTML code. Unlike the type string, show does not escape a html value in an HTML context. For example:

<div>
    {{ "<b>this is bold</b>" }}           is escaped
    {{ html("<b>this is bold</b>") }}     is not escaped
</div>
&lt;b&gt;this is bold&lt;/b&gt;
<b>this is bold</b>

A value with type string can be converted to the html type only if it is an untyped constant, as "<b>this is bold</b>". If it is a variable, it cannot be converted. On the other hand, a html type value can always be converted to the string type.

{%%
    var a html = "<b>this is bold</b>"  // "<b>this is bold</b>" can be converted to html
    var b string = a                    // a can be coverted to b
    var c html = b                      // ERROR: b cannot be converted to html
%%}

markdown

The markdown type is a string type representing Markdown code. Unlike the type string, show does not escape a markdown value in a Markdown context. For example, supposing a Markdown context:

{{ "# This is a title" }}
{{ markdown("# This Is A Title") }}
\# This is a title
# This is a title

The markdown type, the html type and the css, js and json types are called format types. These format types can be converted to the string type only if the value to convert is an untyped constant as seen in the example for the html type.

int

Values with type int are integer numbers. These are examples of int variable declarations:

{% var a int %}  a is 0
{% var b = 5 %}  b is 5
{% c := 7 %}     c is 7

slice

A slice is a numbered sequence of elements of the same type. For example []int{5, 2, 7, 9} is a slice of int values and []string{"hello", "ciao"} is a slice of string values. A slice can be nil which is a value other than an empty slice.

These are examples of slice variable declarations:

{% var a []int %}                a is a nil int slice
{% var b = []int{} %}            b is an empty int slice
{% var c = []int{3, 0, 7, 2} %}  c is an int slice with elements 3, 0, 7 and 2
{% d := []int{2, 9, 5} %}        d is an int slice with elements 2, 9 and 5

Length

The len built-in function is used to read the length of a slice, ie the number of elements it contains.

{% var s = []int{"a", "b", "c"} %}
{{ len(s) }}
3

Accessing to an element of a slice

To access an element of a slice use square brackets [ and ] with its index starting from 0. For example:

{% var s = []string{"a", "b", "c"} %}
{% s[1] = "e" %}
{{ s[0] }} {{ s[1] }} {{ s[2] }}
a e c

To access to the last element of a slice s you can write s[len(s)-1].

Accessing a nil slice or accessing a index that does not exist is an error.

Iterate over the elements of a slice

To iterate over the elements of an slice use the for statement. For example:

{% var greetings = []string{"Hello", "Ciao", "你好"} %}

{% for greeting in greetings %}
  {{ greeting }}
{% end %}
  Hello
  Ciao
  你好

Slicing

Slicing is an operation that returns a portion of a slice. To do a slicing use square brackets [ and ] with the initial and final indexes separated with a colon :. The final index is not included in the returned slice.

{% var s = []string{"a", "b", "c", "d", "e"} %}
{{ s[1:3] }}
b
c
{% for x in s[2:5] %} {{ x }} {% end %}
 c  d  e 

A slicing operation does not copy the elements, as a consequence the resulting slice refers the same elements of the original slice.

{% var s = []int{0, 1, 2, 3, 4, 5} %}
{% var p = s[0:3] %}
{% s[0] = 5 %}
{{ p }}
5
1
2

Appends elements to a slice

The length of a slice cannot change, but as you can do a slicing to have a shorter slice, you can append to have a longer slice. The append operation is done with the append built-in function:

{% var s = []int{0, 1} %}
{% s = append(s, 2, 3, 4, 5) %}
{{ s }}
0
1
2
3
4
5

map

A map associates keys with values. Associations have no order. For example the following code defines a map from strings to string values and iterates over the elements of the map using the for range statement:

{%%
   var letters = map[string]string{
       "a": "the letter 'a'",
       "b": "the letter 'b'",
   }
   for key, value := range letters {
        show key, ": ", value, "\n"   
   }   
%%}

If you want a map with string keys and values of any type, use a map[string]any map.

As in Go, the map values can be read with the expression:

{{ letters["a"] }}

In Scriggo, but not Go, you can use dot notation:

{{ letters.a }}

See map selector expressions specification for more details.