*MavoScript* is Mavo's simple expression language, used in Mavo expressions.

Special properties are available on every Mavo and start with a dollar ($) sign. Some of them have more information that you can access with a dot.

Property | Description | Current value(s) |
---|---|---|

`$now` |
Current date and time as number of milliseconds since January 1st, 1970. Mostly useful with date and time functions or the `mod` operator. Updated every 100ms. |
[$now] |

`$startup` |
The value of `$now` when the page loaded. |
[$startup] |

`$today` |
Current date. | [$today] |

`$hash` |
The URL hash (without the `#` sign) |
[$hash] |

`$mouse` |
Mouse coordinates relative to the viewport. Use `$mouse.x` and `$mouse.y` to get them. |
[$mouse.x] [$mouse.y] |

`$index` |
If inside a collection, the closest item’s position in its collection, starting from 0. | |

`$previous` |
If inside a collection, the closest item’s previous item. | |

`$next` |
If inside a collection, the closest item’s next item. |

The following functions are useful with properties that have multiple values, i.e. are on or inside a `mv-multiple`

element.

Function | What it does |
---|---|

`count(property)` |
Count how many items in a list actually have a value. |

`sum(property)` |
Sum all numbers in the list. |

`average(property)` |
Calculate the average of all numbers in the list. |

`min(property)` |
Calculate the minimum of all numbers in the list. |

`max(property)` |
Calculate the maximum of all numbers in the list. |

`last(property)` |
Get the last item |

Usually, you don't need to use a function for the following, you can just use the syntax in the first column.
However, functions may still be useful for applying the operation between all values from a collection. E.g. `add(age)`

where "age" is a property inside a collection will add all ages together (basically the same as `sum(age)`

).

Math | Function | What it does |
---|---|---|

`a + b` |
`add(a, b)` |
Addition |

`a - b` |
`subtract(a, b)` |
Subtraction |

`a * b` |
`multiply(a, b)` |
Multiplication |

`a / b` |
`div(a, b)` |
Division. Note that division by 0 will show up as ±∞ or `NaN` if it’s 0/0. |

`a mod b` |
`mod(a, b)` |
Remainder of a / b. |

`a and b` |
`and(a, b)` |
Check that both a and b have a value |

`a or b` |
`or(a, b)` |
Check that at least a or b have a value |

`!a` |
`not(a)` |
Check if a doesn’t have a value |

`a < b` |
`lt(a, b)` |
Check if a is less than b |

`a <= b` |
`lte(a, b)` |
Check if a is less than, or equal to b |

`a > b` |
`gt(a, b)` |
Check if a is greater than b |

`a >= b` |
`gte(a, b)` |
Check if a is greater than, or equal to b |

`a = b` |
`eq(a, b)` |
Check if a is equal to b |

If you have more operands you don’t need to nest these functions, just provide more parameters.
E.g. you don’t need to do `add(a, add(b, c))`

, `add(a, b, c)`

will just work.

All JavaScript Math functions can be used in Mavo without having to type `Math.`

before them.
For example, to calculate the square root of 4, you don’t need to type `Math.sqrt(4)`

, you can just type `sqrt(4)`

.

Example | Result | What? / Why? |
---|---|---|

`len('foo')` |
3 | "foo" is 3 characters long |

`search('abcd', 'cd')` |
2 | "cd" is in after the 2nd character in "abcd" |

`starts("abcd", "b")` |
false | "abcd" does not start with "b" |

`ends("abcd", "d")` |
true | "abcd" does end with "d" |

`replace("abbbc", "b", "d")` |
"adddc" | Replaced every "b" with "d" |

`replace("abbbbbbc", "bb", "b", 3)` |
"abc" | Replaced every "bb" with "b", then did it again on the result, then again (3 times total). |

`idify("Foo Bar? Baz!")` |
"foo-bar-baz" | Converted "Foo Bar? Baz!" to something more appropriate for use in an id or class attribute. |

`readable("fooBar-baz")` |
"Foo bar baz" | Opposite of `idify()` : converts something id-like to something more human readable. |

`uppercase("Foo")` |
"FOO" | Converts all letters to uppercase. |

`lowercase("Foo")` |
"foo" | Converts all letters to lowercase. |

`from("foo.bar", ".")` |
"bar" | Only get the text after the first "." |

`to("foo.bar", ".")` |
"foo" | Only get the text before the first "." |

`between("foo@gmail.com", "@", ".")` |
"gmail" | Get the text between "@" and "." |

```
filename("http://mavo.io/demos/homepage/
images/photo.jpg?foo=bar#baz")
``` |
"photo.jpg" | Get the filename part of a URL |

`join(multiple, ", ")` |
Display multiple values as text, comma-separated | |

`json(property)` |
Get the value of a property (or any custom data) as JSON |

The following examples assume you have defined a `<time property="date">`

property in your Mavo whose current value is June 13th, 1986 at 8:30:05pm.

Example | Result | What it does |
---|---|---|

`year(date)` |
1986 | Returns the year of a date as a 4 digit number. |

`month(date)` |
6 | Returns the month of a date, as a 1-2 digit number from 1 to 12. |

`weekday(date)` |
5 | Returns the day of the week, as a number from 1 to 7. 1 is Monday, 7 is Sunday. |

`day(date)` |
13 | Returns the day of the month, as a 1-2 digit number from 1 to 31. |

`hour(date)` |
20 | Returns the hour part of the date, as a number in a 24-hour format. |

`minute(date)` |
30 | Returns the minute part of the date, as a 1-2 digit number. |

`second(date)` |
5 | Returns the second part of the date, as a 1-2 digit number. |

`date(date)` |
1986-06-13 | Returns the date part only (without any time information), in ISO format. |

`time(date)` |
20:30:05 | Returns the time part of the date only, in ISO format. |

`minutes('1986-06-13 21:40:45' - date)` |
71 | Converts a number of seconds to a number of minutes, rounded to the lowest integer. In this example, it gives us the number of minutes between the two dates, because subtracting two dates gives us the number of seconds between them. |

`hours('1986-06-13 21:40:45' - date)` |
1 | Converts a number of seconds to a number of hours, rounded to the lowest integer. In this example, it gives us the number of hours between the two dates, because subtracting two dates gives us the number of seconds between them. |

`days('1986-06-10 21:40:45' - date)` |
2 | Converts a number of seconds to a number of days, rounded to the lowest integer. In this example, it gives us the number of days between the two dates, because subtracting two dates gives us the number of seconds between them. |

`weeks('1986-06-01 21:40:45' - date)` |
1 | Converts a number of seconds to a number of weeks, rounded to the lowest integer. In this example, it gives us the number of weeks between the two dates, because subtracting two dates gives us the number of seconds between them. |

`months('1986-01-01' - date)` |
5 | Converts a number of seconds to a number of months, rounded to the lowest integer. In this example, it gives us the number of months between the two dates, because subtracting two dates gives us the number of seconds between them. |

`years('1980-06-14' - date)` |
5 | Converts a number of seconds to a number of years, rounded to the lowest integer. In this example, it gives us the number of years between the two dates, because subtracting two dates gives us the number of seconds between them. |

Most of the functions for extracting date components (month, weekday, etc) also support alternative forms, which you can access by using the dot notation: `name`

, `shortname`

, and `twodigit`

.
Some of these depend on the document language, declared via the `lang`

attribute (the following examples assume `lang="en-GB"`

).

Example | Result | What it does |
---|---|---|

`weekday(date).name` |
Friday | Returns the day of the week of a date, with its full name. |

`weekday(date).shortname` |
Fri | Returns the day of the week of a date, as its shortened full name. |

`month(date).twodigit` |
06 | Returns the month of a date, as a two digit number. |

`month(date).name` |
June | Returns the month of a date, as its full name. |

`year(date).twodigit` |
86 | Returns the year of a date, as a two digit number. |

These are just a few examples, most date component functions support multiple formats.

Function | What it does | Example |
---|---|---|

`url(param)` |
Print out the value of the `foo` parameter from the current page URL. This matches both parameters like `example.com/index.html?foo=bar` and `example.com/index.html/foo/bar` with the former having priority over the latter. |
`url("foo")` |

`url()` |
Print out the URL of the current page. | `url()` |

`if(test, ifyes)` |
Print out `ifyes` if `test` is non-empty, otherwise nothing. |
`if(rating > 3, good)` |

`if(test, ifyes, ifno)` |
Print out `ifyes` if `test` is non-empty, otherwise `ifno` . |
`if(rating > 3, good, bad)` |

MavoScript is based on a subset of JavaScript, with a few simplifications to make it easy to use even by people with no JavaScript knowledge. If a Mavo expression is more advanced than MavoScript, it is automatically parsed as JavaScript, allowing experienced web developers to do more with Mavo expressions.

For those who know JavaScript, these are a few key differences:

JavaScript | MavoScript |
---|---|

Math and logical operations with arrays produce nonsensical results | Array math & logical operations works element-wise. Operations between an array and a scalar are performed on every array element.
This is why things like `count(rating > 3)` work in MavoScript, but wouldn't in JS. |

All strings have to be quoted | Strings that only consist of letters, numbers, and underscores don't need quotes. |

`==` operator for equality |
`=` operator for equality |

`&&` operator for logical and |
`and` operator for logical and |

`||` operator for logical or |
`or` operator for logical or |

`%` operator for remainder |
`mod` operator for remainder |

`if` is a control structure |
`if()` is a function |

`a + b` might be addition or concatenation depending on types |
`a + b` is always addition, `a & b` is concatenation |

Things like `3 > 2 > 1` return unexpected results (`false in this case` ) |
Every operator can have multiple operands, including `>` , so `3 > 2 > 1` has the same result as in math (`true` ) |

`foo.bar.baz` will throw an error if either `foo` or `foo.bar` don’t exist. |
If either `foo` or `foo.bar` don’t exist, `foo.bar.baz` will just return `""` . |

Since MavoScript does not support comments, an easy way to force JS mode is a `/* js */`

comment in the start or end of the expression.