# Syntax

> Delimiters, comments, strings and whitespace.

A Kiln template is ordinary text, usually HTML, with three kinds of delimiters mixed in. Everything outside them is output as written.

| Syntax | Use |
| --- | --- |
| `{{ expression }}` | Output the value of an expression |
| `{% tag %}` | Run a tag, such as `if` or `for` |
| `{# comment #}` | A comment. It produces no output |

page.kiln:

```kiln
{# Greets the signed-in user #}
{% if user %}
	<p>Hello, {{ user.name }}. You have {{ messages }} messages.</p>
{% endif %}
```

Output:

```html
<p>Hello, Ada. You have 3 messages.</p>
```

Comments can span several lines, but they don't nest.

## Whitespace

Kiln removes any line that holds only tags or comments, including its line break. Indent your tags to match your HTML, and the output still comes out clean.

page.kiln:

```kiln
<ul>
	{% for item in items %}
	<li>{{ item }}</li>
	{% endfor %}
</ul>
```

Output:

```html
<ul>
	<li>Tea</li>
	<li>Coffee</li>
</ul>
```

Output tags never remove their line, because they print something.

A byte order mark at the start of a template is ignored, so a file saved with one prints the same as a file without.

To remove whitespace by hand, add a `-` inside a delimiter. It removes all whitespace on that side, including line breaks.

page.kiln:

```kiln
<button>
	{{- label -}}
</button>
```

Output:

```html
<button>Save</button>
```

Every delimiter supports it: `{{-`, `-}}`, `{%-`, `-%}`, `{#-` and `-#}`.

## Indentation

Kiln removes the extra indentation inside a tag, so you can indent a template for reading without it showing in the HTML.

page.kiln:

```kiln
<ul>
	{% for item in items %}
		<li>{{ item }}</li>
	{% endfor %}
</ul>
```

Output:

```html
<ul>
	<li>Tea</li>
	<li>Coffee</li>
</ul>
```

- It applies when an opening tag, such as `for` or `if`, is on a line of its own.
- Kiln removes the indentation that every line inside shares, beyond the tag's own. If one line is indented less, or uses tabs where the others use spaces, nothing is removed.
- Blank lines don't count.
- Nested tags each remove their own step.
- Content that lines up with its tag, as in the example under Whitespace, is unchanged.
- Only text in the template changes. Values you output keep their own whitespace.
- It happens when the template is compiled, so rendering is no slower.

When an `include`, `component`, `slot` or `block` is on a line of its own, Kiln indents every line it inserts to line up with the tag.

page.kiln:

```kiln
<main>
	{% component "components/card" with { title: "Hello" } %}
		<p>Welcome back.</p>
	{% endcomponent %}
</main>
```

components/card.kiln:

```kiln
<article>
	<h2>{{ title }}</h2>
	{% slot %}{% endslot %}
</article>
```

Output:

```html
<main>
	<article>
		<h2>Hello</h2>
		<p>Welcome back.</p>
	</article>
</main>
```

- It applies to the template that an include or component renders, the content passed to a slot, and the blocks a child template fills.
- Nested insertions add up. A slot inside a component inside an include lines up with all three.
- When the tag shares its line with other text, the inserted content is not indented any further.
- Only text in templates is indented. Values you output keep their own whitespace, including what a macro returns and what `set` and `apply` capture.

Kiln never changes the indentation of lines inside a `<pre>` or `<textarea>`, because there the whitespace is part of the content. Content an `include` or `component` inserts there is not indented either. A `<pre>` inside an HTML comment, script or style doesn't count.

## Strings

Strings use single or double quotes. Double-quoted strings can include expressions with `#{ }`:

page.kiln:

```kiln
{{ "Hello #{ user.name|title }, you have #{ count } new messages" }}
```

Output:

```html
Hello Ada, you have 2 new messages
```

Both quote styles support the escapes `\\`, `\'`, `\"`, `\n`, `\r`, `\t` and `\u{hex}`. In a double-quoted string, write `\#{` for a literal `#{`. Single-quoted strings never interpolate, so `'#{'` is already literal there, and `\#` is an error.

## Names

Variable, function and filter names start with a letter or underscore, followed by letters, digits or underscores. They are case-sensitive. Kiln's own names use camelCase, such as `formatDate` and `loop.revIndex`.

These words are reserved and can't be variable names: `true`, `false`, `null`, `and`, `or`, `not`, `in`, `is`, `loop` and `slots`.

## Template names

Templates are named by their path, such as `pages/home.kiln` or `components/card`.

- The `.kiln` extension is optional. A name whose last part already holds a dot, such as `data/config.json`, is used as written, so write `partials/nav.main.kiln` in full.
- Names starting with `./` or `../` are relative to the current template.
- Other names are relative to the loader's root folder.
- A name can't point above the root folder, or name a folder, such as `./` or `partials/`.
