Društvo LJUDMILA
Rozmanova ulica 12
1000 Ljubljana
Slovenia
Prostori: osmo/za

XppTemplates

The template consists of a series of statements. Statements must be separated by whitespace and/or ";". Some statements can be followed by blocks marked with "{" and "}".

Tag generator

A css-like "selector" will generate an html tag with optional content in a {} block.

Basic tag generation

The simplest form is just the tag name:

div
<div></div>

To include children elements, use a {} block:

div {
 span
}
<div><span></span><div>

Void elements allowed in HTML5 are taken into account:

br input
<br><input>

Ids, class names, attributes

You can specify the id and class names:

span#highest.stat.green
<span id="highest" class="stat green">

If you don't specify a tag, div is used by default:

#canvas {
 .content
}
<div id="canvas"><div class="content"></div></div>

You can specify attributes:

input[type = "text"][value = "Hello!"]
<input type="text" value="hello">
input[type = "checkbox"][checked]
<input type="checkbox" checked">

Escape and calculate ids and class names

Ids, classnames and class names can contain only alphanumeric characters, underscores and dashes.

If you need to include space or another character, escape the whole value by enclosing it in quotes:

#"my div"."@myclass"
<div id="my div" class="@myclass"></div>

If you need to calculate the value or use a variable, use () to enclose an expression:

#("app-" $appId).($appClass)
<div id="app-myApp" class="myAppClass"></div>

If the value evaluates to false or an empty string, it will be ignored. In the example, $appActive is false.

#("app-" $appId).($appActive && 'active')
<div id="app-myApp"></div>

Calculate attributes

Attributes values are expressions and don't need to contain just a string:

input#docName[value = "document " $docCounter]
<input id="docName" value="document 2">

If you need to calculate the attribute name, use () to enclose an expression:

#("app-" $appId).($appClass)
<div id="app-myApp" class="myAppClass"></div>

If the name evaluates to false or an empty string, the attribute will be ignored:

input[type="text"][($label && "placeholder")="enter " $label]
<input type="text" placeholder = "enter name"> <input type="text">

This is especially useful for attributes that don't take a value:

input#field[type="checkbox"][($field && "checked")]
<input id="field" type="checkbox" checked> <input id="field" type="checkbox">

Strings

You can include text in your template by enclosing it in quotes:

"Hello world"
Hello world

Double quotes will escape the text for HTML, single quotes will not:

"This is an input: <input>" br

'This is really an input: <input>'

$name
This is an input: &lt;input&gt;<br>This is really an input: <input>

Attribute values will always be escaped.

Escapes and special characters

Use \" and \' to escape quote characters. You can also use \n \t and even \r if you really need to. Use \\ for backslash.

Multiline strings

Strings can span lines. All the white text is included:

"Some text in two lines"
Some text in two lines

A string that begins at the end of a line (ignoring any whitespace) will end only when a matching quote is found at the beginning of one of the following lines (again ignoring whitespace). This allows you to not worry about escaping quotes, and makes text blocks prettier to look at:

"

Little bot says "Hello!" and then coredumps on the next line

"
Little bot says "Hello!" and then coredumps on the next line

Operators

Logical

You can use the two familiar logical operators from javascript:

||
or - if left side is true, return left side, else return right side.
&&
and - if left side is true, right right side, else return false.
3>2 && 2>3 // false <br>
3>2 || 2<3 // true

Logical operators are shortircuiting:

"foo" || "bar" // "foo"

"" || "bar" // "bar" "foo" && "bar" // "bar"

"" && "bar" // ""

Comparison

You can use the usual comparison operators (==,!=,>,<,>=,<=):

if (3>2) { "3 is really more than 2" } else { "cosmic ray"}
3 is really more than 2

You can chain comparisons, like in paper maths:

4 > 3 > 2 == 2 // this is true "a" < "b" < "b" // this is false

If you want to compare two comparisons, use brackets to group them:

(3<2) == (4<3) // both are false, so this is true

Arithmetics

You can use the usual arithmetic operators:

+ -
for addition and subtraction
* / %
for multiplication, division and modulus

Negation

-
arithmetic negation
!
logical negation

Apply

If you want to use members of an object or an array as arguments in an array, use the application operator ->:

template compare () {
 if ($a>$b) { $a " is more than " $b }
 else if ($a<$b) { $a " is less than " $b }
 else { $a " equals " $b }

}

obj(a=3,b=4)->compare()
3 is less than 4

if else

if (expr) {
 // statements 

} else if (expr) {

 // statements

} else {

 // statements
}

Unlike in JavaScript, braces are obligatory. You can also write "elseif" if you prefer.

each

each (expr) {
 statements  
}

The expression will be evaluated, and if it evaluates to a list, it will be iterated. On each iteration, the cursor will be set to the next item, and the block evaluated.

The current value is accessible as $, and the current index is $#.

{
 options:{ foo: 'A foo', bar: 'A bar' },
 value: 'bar'

}

each ($options) {

 option[value = $#][selected ?= $==$value] { $ }
}
<option value="foo">A foo</option> <option value="bar" selected>A bar</option>


If the current item is a list of its own, its items are accessed with $.itemkey

{
 persons: [
   {name:'Alice',city:'Alacant'},
   {name:'Berlin',city:'Berlin'},
 ]

} ---- each ($persons) {

 $.name; " lives in " ; $.city
 br
}
Alice lives in Alacant<br> Bob lives in Berlin<br>

If the item key contains a space or other special characters, you can enclose it in quotes. If you need to calculate the item key, enclose the expression in ().

$persons."John Doe".city $persons.($who).city

template

You can define templates and then call them in the same way as built-in functions. Use $1, $2, etc. to access the arguments:

template person() {
 $1; " lives in "; $2
 br

} person("Alice","Alacant")

person("Bob","Berlin")
Alice lives in Alacant<br> Bob lives in Berlin<br>

Arguments can be named:

template person() {
 $name; " lives in "; $city
 br

} person(name = "Alice",city = "Alacant")

person(name = "Bob",city = "Berlin")
Alice lives in Alacant<br> Bob lives in Berlin<br>

Arguments can have default values:

template person(city="an unknown city") {
 $name; " lives in "; $city
 br

}

person(name = "Claire")
Claire lives in an unknown city<br>

If you have an object which contains the arguments you want to pass, use the apply operator "->".

{
 persons: [
   {name:'Alice',city:'Alacant'},
   {name:'Berlin',city:'Berlin'},
 ]

} ---- template person() {

 $name; " lives in "; $city
 br

}

each ($persons) {

 $->person();
}
Alice lives in Alacant<br> Bob lives in Berlin<br>