# Coming from Twig

> What is the same, what changed and why.

Kiln's syntax is close to Twig's, so most templates read the same. The differences fix things that tend to cause bugs, follow JavaScript where Twig follows PHP, or remove features a website doesn't need.

## Renamed

| Twig | Kiln |
| --- | --- |
| `embed` | [`component`](https://kilnlang.com/docs/tags/component/) with `slot` and `fill` |
| `types` | [`props`](https://kilnlang.com/docs/tags/props/), which also checks values and sets defaults |
| `json_encode` | `json` |
| `number_format` | `formatNumber`, with `Intl` options |
| `date` filter | `formatDate`, with `Intl` options instead of formats like `"Y-m-d"` |
| `striptags`, `url_encode` | `stripTags`, `urlEncode` |
| `loop.revindex` | `loop.revIndex` |
| `escape("html_attr")` | `escape("attr")` |
| `_self.macro()` | `macro()` |

All of Kiln's names are camelCase, like JavaScript.

## Changed

| Area | Twig | Kiln |
| --- | --- | --- |
| Missing variables | Empty, unless `strict_variables` is on | An error, unless you turn off [strict mode](https://kilnlang.com/docs/language/strict-mode/) |
| `include` and components | Share the caller's variables unless you add `only` | Only see what you pass, plus globals |
| Imports | Hidden in some places, such as inside an embed | Work everywhere in the template that declares them |
| `==` | Loose, with PHP's rules | Strict, like `===` |
| True and false | `"0"` is false | `"0"` is true. Empty arrays and hashes are false |
| Printing booleans | `1` and nothing | `true` and `false` |
| `+` | Converts numeric strings | Numbers only |
| `in` on a hash | Checks values | Checks keys |
| `~` | Runs before `+` | Runs after `+` |
| Named arguments | Matched to parameter names | Gathered into one hash at the end, except for macros |
| Property access | `attribute()` for dynamic names | `obj[name]` works everywhere |
| Method calls | Any public method | Only methods a class [exposes](https://kilnlang.com/docs/api/safe-markup/#class-instances) |
| Timestamps | Seconds | Milliseconds, like JavaScript |
| `slice` | Start and length | Start and end, like JavaScript |
| Whitespace | Removes the first newline after a tag | Removes lines that only hold tags, and the extra indentation inside tags. Indents inserted content to line up with its tag |
| Async | Not supported | Any call can return a promise |
| `flush` | Sends the output so far | Closes the outlets above it, so a [streamed](https://kilnlang.com/docs/api/streaming/) page can be sent up to it |

## Removed

- **Tags:** `sandbox`, `use`, `deprecated`, `do` and `guard`. Kiln's [safety model](https://kilnlang.com/docs/api/safety/) replaces the sandbox.
- **Functions:** `include()`, `attribute`, `constant`, `source`, `template_from_string` and `random`. Use the `include` tag and `[]` instead of the first two.
- **Filters:** `spaceless`, `convert_encoding`, `format`, `date_modify` and the `e` alias. Use `-` to trim whitespace, and `#{ }` to build strings.
- **Tests:** `same as`, `constant` and `none`. `==` is already strict, and `null` replaces `none`.
- **Syntax:** the `matches` operator, bitwise operators, `items[1:3]` slices, letter ranges such as `'a'..'z'`, `loop.parent`, the `only` keyword, upper-case `TRUE`, `FALSE` and `NULL`, and custom delimiters.
