# Templating Deft's server-side templating is built on **block literals** — `[html ... \html]`, `[sql ... \sql]`, `[codeblock ... \codeblock]`. A block is a multi-line literal whose interior is tokenized: literal text, `$var` interpolation, and nested `[...]` calls all mix freely. The compiler packages the interior as a tagged map and calls the block-named function, which applies domain-appropriate escaping and returns the rendered result. ## How blocks work `[name ... \name]` desugars to a single ordinary call:
 [name %{ :parts @[ part1 part2 ... ] }] 
- The block name resolves through the normal namespace chain — it is just a function. The `html` function comes from `from "deft/stdext/html" import @{ html html-raw }`; you can define your own block handlers the same way. - `:parts` is a vector of already-evaluated parts: | Part | Shape | Meaning | |---|---|---| | string | `"text"` | Literal block text — emit unchanged | | `$var` | `%__escape{:value ...}` | Interpolated value — apply domain escaping | | trusted | `%__HtmlSafe{...}` / `%__SqlSafe{...}` | Pre-escaped — pass through | | list | `@[ ... ]` | Collected results (e.g. `for` loop bodies) — recurse and join | The handler's job: walk the parts, escape each per its domain, and join. That is the entire contract — see [Defining your own templates](#defining-your-own-templates). ## `[html ... \html]` The workhorse. Returns a `%__HtmlSafe{:value ...}` tagged map (a plain string that knows it is safe for embedding).
 from "deft/stdext/html" import @{ html html-raw html-escape }

def render-user {| user^map |
    [html
        <div class="user">
            <h1>$user~name</h1>
            <p>Age: $user~age</p>
        </div>
    \html]
}

def handler {|req res|
    http/html $res [render-user $alice]
} 
### Interpolation forms Any form from string interpolation works inside a block: | Form | Example | Notes | |---|---|---| | `$var` | `$name` | Variable or `$user~field` chain | | `$var(args)` | `$xs(len)` | Postfix call | | `$(expr)` | `$($price * $quantity)` | Infix expression | | `$[cmd]` | `$[upper $name]` | Prefix call — result used verbatim | | `[cmd]` | `[upper $name]` | Bare bracket call also interpolates | Escape a literal `[` as `\[`. ### Escaping is explicit A block is a **raw** template: interpolated `$var` values pass through **unescaped**. Escape dynamic text explicitly: - `[html-escape $text]` — entity-escape (`&` `<` `>` `"` `'`) for safe text interpolation. - `[html-raw $markup]` — mark a string as trusted HTML (no escaping).
 set bio "<b>bold</b>"

[html
    <p>[html-escape $bio]</p>   # &lt;b&gt;bold&lt;/b&gt;
    <p>[html-raw $bio]</p>      # <b>bold</b>
\html] 
Anything wrapped in `__HtmlSafe` (the result of `[html ... \html]` or `[html-raw ...]`) passes through nested blocks unchanged — that is how partials compose. ### Partials and nesting A function that returns `[html ... \html]` can be embedded directly in an outer block:
 def render-user {| user^map |
    [html <h1>$user~name</h1> \html]
}

[html
    <div class="card">
        [render-user $user]
    </div>
\html] 
### Loops A bracketed `[for ...]` inside a block collects each iteration's body results into a list part, which the handler joins. Emit a nested `[html ... \html]` block per item:
 def user-list {| users^list |
    [html
        <ul>
        [for u $users {
            [html <li>[html-escape $u~name]</li> \html]
        }]
        </ul>
    \html]
} 
### Raw blocks `[*name ... \name]` captures the interior **verbatim** — no `$var` or `[cmd]` interpolation at all. Useful for source listings:
 [*codeblock
    set x $who
    [str $x]
\codeblock]        # $who stays literal; the block is syntax-highlighted 
## Defining your own templates Any function of one argument can be a block handler. The block map arrives as `%{ :parts @[...] }` tagged with the block name; unwrap each part by type and apply your own escaping rules.
 def block-part-str {| part |
    if ([type $part] == "__escape") {
        # $var interpolation — apply your own escaping here
        [str [get $part :value]]
    } else if ([type $part] == "__HtmlSafe") or ([type $part] == "__SqlSafe") {
        # pre-escaped content — trust it
        [str [get $part :value]]
    } else if [is? "list" $part] {
        # collected loop bodies — recurse and join
        [join [collect [map $part {[block-part-str $it]}]] ""]
    } else {
        # literal text
        [str $part]
    }
}

def my-pill {| block^map |
    set body [join [collect [map [get $block :parts] {[block-part-str $it]}]] ""]
    [html <span class="pill">$body</span> \html]
}

[my-pill
    hi $who
\my-pill]        # → <span class="pill">hi world</span> 
Return an `__HtmlSafe` value (via `[html ... \html]` or `[html-raw ...]`) so your template nests safely inside other blocks. The stdext package's `html.dft` and `sql.dft` are the reference implementations: - `packages/stdext/src/html.dft` — `html`, `html-raw`, `html-escape` - `packages/stdext/src/sql.dft` — `sql`, `sql-raw`, `sql-escape-value` ## `[sql ... \sql]` — another example The same block machinery, with SQL-aware escaping. Where `html` is string-based, `sql` escapes values by their Deft type: | Value | SQL literal | |---|---| | string | `'O''Brien'` (single-quoted, quotes doubled) | | number | `42`, `3.14` | | boolean | `TRUE` / `FALSE` | | nil | `NULL` | | list | `(1, 2, 'text')` | | map | `"col" = 'val' AND ...` (WHERE-style) |
 from "deft/stdext/sql" import @{ sql sql-raw }

set name "O'Brien"
set id 42
set active true

set query [sql
    SELECT * FROM users
    WHERE name = $name AND id = $id AND active = $active
\sql]

# SELECT * FROM users
# WHERE name = 'O''Brien' AND id = 42 AND active = TRUE 
Use `[sql-raw ...]` for trusted fragments the type-aware escaper would mangle — function calls, identifiers, operators:
 [sql
    SELECT * FROM users
    WHERE updated_at > [sql-raw "NOW() - INTERVAL '1 day'"]
\sql] 
Pairs naturally with `sqlite/query`:
 set rows [sqlite/query $db [sql
    SELECT * FROM users WHERE name = $name
\sql]] 
## Quick Reference | Form | Purpose | |---|---| | `[html ... \html]` | Render an HTML fragment; returns `__HtmlSafe` | | `[html-raw $x]` | Mark a string as trusted HTML | | `[html-escape $x]` | Entity-escape text for safe interpolation | | `[sql ... \sql]` | Build a SQL string with type-aware value escaping | | `[sql-raw $x]` | Mark a fragment as trusted SQL | | `[*name ... \name]` | Any block, captured verbatim (no interpolation) | | `[myname ... \myname]` | Your own block handler — any 1-arg function |