# Core tags and attributes

Marko provides a number of tags

## Control flow

### `<if>`, `<else-if>`, `<else>`

The `<if>`, `<else-if>`, and `<else>` tags provide conditional control-flow for templates.

```xml
<if(arriving)>
    <div>Hey there</div>
</if>
<else-if(leaving)>
    <div>Bye now</div>
</else-if>
<else>
    <div>What's up?</div>
</else>
```

Conditionals may also be applied as attributes:

```xml
<div if(arriving)>Hey there</div>
<div else-if(leaving)>Bye now</div>
<div else>What's up?</div>
```

And support complex expressions:

```xml
<if(Math.random() > 0.5)>
    <div>50-50 chance of seeing this</div>
</if>
```

### `<for>`

The `<for>` tag allows iterating over an array of items:
```xml
<ul>
    <for(color in colors)>
        <li>${color}</li>
    </for>
</ul>
```

It may also be applied as an attribute:
```xml
<ul>
    <li for(color in colors)>${color}</li>
</ul>
```

With either of the above templates, and the following value for `colors`:

```js
var colors = ['red', 'green', 'blue'];
```

The output HTML would be the following:

```html
<ul>
    <li>red</li>
    <li>green</li>
    <li>blue</li>
</ul>
```

#### Loop Status Variable

The `for` directive also supports a loop status variable in case you need to know the current loop index. For example:

```xml
<ul>
    <li for(color in colors | status-var=loop)>
        ${color}
        ${loop.getIndex()+1}) of ${loop.getLength()}
        <if(loop.isFirst())> - FIRST</if>
        <if(loop.isLast())> - LAST</if>
    </li>
</ul>
```

#### Loop Separator

```xml
<for(color in colors | separator=", ")>${color}</for>
<div>
    <span for(color in colors | separator=", ") style="color: ${color}">
        ${color}
    </span>
</div>
```

#### Range Looping

A range can be provided in the following format; `<var-name> from <from> to <to>[ step <step>]`.

The `from`, `to` and `step` values must be numerical expressions. If not specified, step defaults to 1.

```xml
<ul>
    <li for(i from 0 to 10)>
        ${i}
    </li>
</ul>
```

```xml
<ul>
    <li for(i from 0 to 10 step 2)>
        ${i}
    </li>
</ul>
```

```xml
<ul>
    <li for(i from 0 to myArray.length-1)>
        ${myArray[i]}
    </li>
</ul>
```

#### Property Looping

```xml
<ul>
    <li for(name, value in settings)>
        <b>${name}</b>: ${value}
    </li>
</ul>
```

#### Native JavaScript for-loop

```xml
<for(var i=1; i<=3; i++)>
    ${i}
</for>
```

#### Custom Iterator


```xml
static function reverseIterator(arrayList, callback) {
    for(var i=arrayList.length-1; i>=0; i--){
        callback(arrayList[i]);
    }
}

<div for(item in ['a', 'b', 'c'] | iterator=reverseIterator)>
    ${item}
</div>
```

Output:

```html
<div>c</div>
<div>b</div>
<div>a</div>
```

### `<while>`

Any element can be repeated until a condition is met by using the `while` directive. The directive can be applied as an element or as an attribute.

_Applied as an attribute:_

```xml
$ var n = 0;

<ul>
    <li while(n < 4)>
        ${n++}
    </li>
</ul>
```

_Applied as an element:_

```xml
$ var n = 0;

<ul>
    <while(n < 4)>
        <li>${n++}</li>
    </while>
</ul>
```

### `body-only-if`


If you find that you have a wrapper element that is conditional, but whose body should always be rendered then you can use the `body-only-if` attribute to handle this use case. For example, to only render a wrapping `<a>` tag if there is a valid URL then you could do the following:

```xml
<a href=input.linkUrl body-only-if(!input.linkUrl)>
    Some body content
</a>
```

Given a value of `"http://localhost/"` for the `input.linkUrl` variable: , the output would be the following:

```xml
<a href="http://localhost/">
    Some body content
</a>
```

Given a value of `undefined` for the `input.linkUrl` variable: , the output would be the following:

```xml
Some body content
```

## JavaScript

The following tags are always written using the [concise syntax](), even when using HTML syntax for tags that generate HTML output.

### `import`
> **Static:** The code generated by `import` will run once when the template is loaded and be shared by all calls to render. It must be declared as a top level tag and does not have access to `data`, `state`, or other values passed in at render.

The `import` tag is used to access data and functions from external files.  It follows the same syntax as the [JavaScript `import` statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import).

```xml
import sum from './utils/sum';
<div>The sum of 2 + 3 is ${sum(2, 3)}</div>
```

### `<export>`
> **Static:** The code generated by `export` will run once when the template is loaded and be shared by all calls to render. It must be declared as a top level tag and does not have access to `data`, `state`, or other values passed in at render.

The `export` tag is used to export values from the template.  It follows the same syntax as the [JavaScript `export` statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export), but only named exports are supported (the default export is the template).

```xml
export var route = '/about';

<!doctype html>
<html>
    <body>
        <h1>About us</h1>
    </body>
</html>
```

## Reusable content

### `<include>`

The include tag is used to embed another template (or part of another template) in the current template.

The include tag can take a path to a template as the first argument:

```xml
<include('./path/to/template.marko')/>
```

The second argument may be used to pass input to the included template:

```xml
<include('./path/to/template.marko', { name:'Frank' })/>
```

Attributes may also be used to pass data to the included template and can be used in combination with the input parameter:

```xml
<include('./path/to/template.marko', data) name="Frank"/>
```

#### Layouts with nested attributes

In addition to including external content, you can inject additional content chunks into the external content.  This is accomplished by using nested attribute tags which are denoted by the `@` symbol:

_page.marko_
```xml
<include('./layout.marko')>
    <@body>
        <h1>Hello Marko</h1>
    </@body>
</include>
```

Then in your layout template you can include the injected content:

_layout.marko_
```xml
<!doctype html>
<html>
    <body>
        <!-- this comes from <@body> -->
        <include(input.body)/>
    </body>
</html>
```

<!--
- You can use many nested attribute tags for multiple injection points
- You can have repeated nested attribute tags by using `marko-tag.json` (components only)
- You can add additional attributes to an nested attribute tag
- You can pass data to a nested attribute tag's body?
-->

### `<include-text>`

```xml
<include-text('./foo.txt')/>
```

Special HTML characters will be escaped. If you do not want escaping then use the `<include-html>` tag (see below).

### `<include-html>`

```xml
<include-html('./foo.html')/>
```

Special HTML characters will _not_ be escaped since the file is expected to be an HTML file.

### `<macro>`



## Awaiting promises

### `<await>`


## Comments

Standard HTML comments can be used to add comments to your template. The HTML comments will not show up in the rendered HTML.

Example comments:

```xml
<!-- This is a comment that will not be rendered -->
<h1>Hello</h1>
```

If you would like for your HTML comment to show up in the final output then you can use the custom `html-comment` tag.

### `<html-comment>`

```xml
<html-comment>This is a comment that *will* be rendered</html-comment>
<h1>Hello</h1>
```

Output:

```xml
<!--This is a comment that *will* be rendered-->
<h1>Hello</h1>
```

## Compiler options

### `preserve-whitespace`

