### Express Adapter Usage Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/configuration.md Example of configuring and using the Express adapter with a specified template directory. ```typescript import { adapter } from '@nds-stack/bun-html' import express from 'express' const app = express() app.engine('html', adapter.express({ dir: './views' })) ``` -------------------------------- ### Hono Adapter Usage Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/configuration.md Example of configuring and using the Hono adapter with a specified template directory. ```typescript import { Hono } from 'hono' import { adapter } from '@nds-stack/bun-html' const app = new Hono() app.use('*', adapter.hono({ dir: './views' })) ``` -------------------------------- ### Complete Configuration Example with Hono Adapter Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/configuration.md A full example demonstrating the integration of the Hono adapter with custom route-specific helpers. ```typescript import { render, adapter } from '@nds-stack/bun-html' import { Hono } from 'hono' const app = new Hono() // Register adapter with full configuration app.use('*', adapter.hono({ dir: './templates', cache: true, autoescape: true })) // Use with additional helpers per-route app.get('/greeting/:name', async (c) => { const template = 'Hello {{name}}, {{greeting}}' const data = { name: c.req.param('name') } const html = await c.var.render(template, data, { helpers: { greeting(this: any) { const hour = new Date().getHours() if (hour < 12) return 'Good morning' if (hour < 18) return 'Good afternoon' return 'Good evening' } } }) return c.html(html) }) export default app ``` -------------------------------- ### Context Stack Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/parser.md Example demonstrating how to access parent context variables using the '../' prefix within nested loops. ```html render(` {{#each groups}} {{#each items}} {{../../title}} // Access groups' parent context {{/each}} {{/each}} `, { title: 'Root', groups: [...] }) ``` -------------------------------- ### Real-World Example Source: https://github.com/nds-stack/bun-html/blob/main/README.md An example demonstrating how to use @nds-stack/bun-html to render a list of users with conditional formatting. ```typescript import { render } from '@nds-stack/bun-html' const users = [ { name: 'Alice', role: 'admin' }, { name: 'Bob', role: 'user' }, ] const template = ` ` const html = render(template, { users }) // ``` -------------------------------- ### Expression System Examples Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/README.md Examples of conditional expressions in {{#if}} and {{#unless}} tags. ```typescript {{#if age >= 18}}Adult{{/if}} {{#if user.active && !banned}}Welcome{{/if}} {{#unless ../published}}Draft{{/unless}} ``` -------------------------------- ### Framework Adapters Source: https://github.com/nds-stack/bun-html/blob/main/README.md Shows examples of using adapters for Express and Hono. ```typescript import { adapter } from '@nds-stack/bun-html' // Express — returns (filePath, data, callback) for app.engine() adapter.express({ dir: './views' }) // Hono — returns middleware that adds c.var.render() adapter.hono({ dir: './views' }) ``` -------------------------------- ### Layouts Source: https://github.com/nds-stack/bun-html/blob/main/README.md Example of using layouts with a specified directory. ```typescript await render('{{#layout "main"}}{{content}}{{/layout}}', data, { partialsDir: './layouts', }) // layouts/main.html: {{content}} ``` -------------------------------- ### Async with partials Source: https://github.com/nds-stack/bun-html/blob/main/README.md Example of using async partials with a specified directory. ```typescript await render('{{> header}}
{{content}}
{{> footer}}', data, { partialsDir: './partials', }) ``` -------------------------------- ### Layouts: {{#layout}} Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Demonstrates wrapping content in a layout template using {{#layout}}. ```html Layout file (`views/main.html`): ```html {{title}}
{{content}}
``` Template file (`views/page.html`): ```html {{#layout "main"}}

{{title}}

{{body}}

{{/layout}} ``` ``` ```typescript const html = await render( '{{#layout "main"}}

{{title}}

{{body}}

{{/layout}}', { title: 'Home', body: 'Welcome to the site' }, { partialsDir: './views' } ) ``` ```html Result: ```html Home

Home

Welcome to the site

``` ``` -------------------------------- ### Autoescape example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/configuration.md Illustrates the behavior of `autoescape` with both default and disabled settings, and raw output. ```typescript import { render } from '@nds-stack/bun-html' const untrusted = '' // With autoescape (default, safe) const safe = render('
{{content}}
', { content: untrusted }) // → '
<script>alert("xss")</script>
' // With autoescape disabled (unsafe with untrusted data) const unsafe = render( '
{{content}}
', { content: untrusted }, { autoescape: false } ) // → '
' // Raw output (intentional HTML, default respects autoescape setting) const html = render( '
{{{markup}}}
', { markup: 'Bold' }, { autoescape: true } ) // → '
Bold
' (escaping bypassed for {{{...}}}) ``` -------------------------------- ### Compiled template example Source: https://github.com/nds-stack/bun-html/blob/main/README.md Example of a compiled template module and an auto-generated barrel file. ```typescript // dist/views/home.html.js export default function(data, helpers, escapeHTML) { // ... compiled template code return $ } // dist/views/index.js (auto-generated barrel) import home_html from './home.html.js' import partials_card_html from './partials/card.html.js' export { home_html, partials_card_html } ``` -------------------------------- ### Comments Source: https://github.com/nds-stack/bun-html/blob/main/README.md Example showing how comments are handled and rendered. ```typescript render('Hello{{! this is a comment }}World', {}) // → 'HelloWorld' ``` -------------------------------- ### parseExpression() Examples Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/expression.md Examples of parsing different types of expression strings. ```typescript import { parseExpression } from '@nds-stack/bun-html/expression.js' // Internal API // Simple comparison const ast1 = parseExpression('age > 18') // → { type: 'BinaryOp', op: '>', left: { type: 'Identifier', path: ['age'] }, right: { type: 'Number', value: 18 } } // Complex condition const ast2 = parseExpression('user.active && role == "admin"') // → { type: 'BinaryOp', op: '&&', left: { ... }, right: { ... } } // Parent context const ast3 = parseExpression('../isPublished || this.draft') // → { type: 'BinaryOp', op: '||', left: { type: 'Identifier', path: ['..', 'isPublished'] }, ... } // Grouped condition const ast4 = parseExpression('(x > 5) && (y < 10)') // → { type: 'BinaryOp', op: '&&', left: { ... }, right: { ... } } ``` -------------------------------- ### Async rendering with partials Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/configuration.md Example demonstrating how to use `partialsDir` for asynchronous rendering with partial templates. ```typescript import { render } from '@nds-stack/bun-html' // Async rendering with partials const html = await render( '{{> header}}
{{content}}
{{> footer}}', { content: 'Page content' }, { partialsDir: './templates/partials' } ) ``` -------------------------------- ### Cache management example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/configuration.md Demonstrates using `render` with caching options and manual cache invalidation functions. ```typescript import { render, clearCache, purgeTemplate } from '@nds-stack/bun-html' // Cached (default) const r1 = render('

{{x}}

', { x: 1 }) // Skip cache for this render const r2 = render('

{{x}}

', { x: 2 }, { cache: false }) // Manually invalidate one template purgeTemplate('

{{x}}

') // Invalidate all caches clearCache() ``` -------------------------------- ### Negation Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/parser.md Example of a negation expression and its parsed AST representation. ```typescript // Negation: !active // Parsed as: UnaryNot(Identifier(active)) ``` -------------------------------- ### Plugins - afterRender Source: https://github.com/nds-stack/bun-html/blob/main/README.md Example of a plugin that transforms the output after rendering. ```typescript const uppercasePlugin = { name: 'uppercase', afterRender(output: string) { return output.toUpperCase() }, } render('Hello {{name}}', { name: 'World' }, { plugins: [uppercasePlugin] }) // → 'HELLO WORLD' ``` -------------------------------- ### Hono Adapter Source: https://github.com/nds-stack/bun-html/blob/main/README.md Example of integrating bun-html with the Hono framework. ```typescript import { Hono } from 'hono' import { adapter } from '@nds-stack/bun-html' const app = new Hono() app.use('*', adapter.hono({ dir: './views' })) app.get('/', (c) => { return c.html(c.var.render('

{{title}}

', { title: 'Hello' })) }) ``` -------------------------------- ### {{#with}} usage Source: https://github.com/nds-stack/bun-html/blob/main/README.md Example demonstrating the usage of the {{#with}} block. ```typescript render('{{#with user}}

{{name}}

{{/with}}', { user: { name: 'Alice' } }) // → '

Alice

' ``` -------------------------------- ### Simple Comparison Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/parser.md Example of a simple comparison expression and its parsed AST representation. ```typescript // Simple comparison: age > 18 // Parsed as: BinaryOp(>, Identifier(age), Number(18)) ``` -------------------------------- ### Partials: {{> partial}} Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Shows how to include another template file using the {{> partial}} syntax and the requirements for rendering. ```html views/ ├── header.html (
{{title}}
) ├── footer.html () └── index.html ({{> header}}
{{content}}
{{> footer}}) ``` ```typescript const html = await render( '
{{> header}}
{{content}}
{{> footer}}
', { title: 'Home', content: 'Welcome' }, { partialsDir: './views' } ) // Loads ./views/header.html and ./views/footer.html ``` -------------------------------- ### Express Adapter Source: https://github.com/nds-stack/bun-html/blob/main/README.md Example of integrating bun-html with the Express framework. ```typescript import { adapter } from '@nds-stack/bun-html' app.engine('html', adapter.express({ dir: './views' })) app.set('view engine', 'html') app.get('/', (req, res) => { res.render('index', { title: 'Hello' }) // renders ./views/index.html }) ``` -------------------------------- ### Basic rendering Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/README.md Example of basic rendering with a simple template and data. ```typescript import { render } from '@nds-stack/bun-html' const html = render('

{{title}}

', { title: 'Hello' }) ``` -------------------------------- ### Importing Types Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/types.md Example of how to import various types from the @nds-stack/bun-html package. ```typescript import type { Token, ASTNode, RenderOptions, CompiledTemplate, ExprNode, // Also available as individual node types: ASTNodeText, ASTNodeVariable, ASTNodeRawVariable, ASTNodeEach, ASTNodeIf, ASTNodeUnless, ASTNodeWith, ASTNodePartial, ASTNodeLayout, } from '@nds-stack/bun-html' ``` -------------------------------- ### Whitespace control example 1 Source: https://github.com/nds-stack/bun-html/blob/main/README.md Demonstrates stripping whitespace around a variable using `{{~val~}}`. ```ts render('item = {{~val~}} end', { val: 'x' }) // → 'item = xend' (whitespace around val stripped) ``` -------------------------------- ### Conditional Example: Expression Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Demonstrates conditional rendering using {{#if}} with a comparison expression. ```typescript render( '\n {{#if age >= 18}}\n

You are an adult

\n {{else}}\n

You are a minor

\n {{/if}}\n', { age: 25 } ) // → '

You are an adult

' ``` -------------------------------- ### Raw Output Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Illustrates using triple braces `{{{...}}}` for raw output that bypasses escaping. ```typescript render( '
{{{content}}}
', { content: 'Bold' }, { autoescape: true } // default ) // → '
Bold
' ``` -------------------------------- ### Helper Function Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Shows how to define and use custom helper functions in templates. ```typescript render( '

{{greeting}}

', { }, { helpers: { greeting(this: unknown) { const hour = new Date().getHours() if (hour < 12) return 'Good morning' if (hour < 18) return 'Good afternoon' return 'Good evening' } } } ) // → '

Good [morning|afternoon|evening]

' ``` -------------------------------- ### Generated Code Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/compiler.md Example of code generated by the Bun HTML compiler for a given template string. ```javascript let $ = "" let __d = data let __h = helpers || {} let __s = [] $ += "Hello " { let _v = __d?.["name"] if (_v === void 0) { let _hf = __h["name"] if (typeof _hf === 'function') _v = _hf.call(__d) } if (_v != null) $ += escapeHTML(String(_v)) } $ += ", you are " { let _v = __d?.["age"] if (_v === void 0) { let _hf = __h["age"] if (typeof _hf === 'function') _v = _hf.call(__d) } if (_v != null) $ += escapeHTML(String(_v)) } $ += " years old" return $ ``` -------------------------------- ### Iteration Example: Nested Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Shows how to handle nested {{#each}} loops and access parent context using '../'. ```typescript render( '\n {{#each groups}}\n

{{name}}

\n \n {{/each}}\n', { groups: [ { name: 'Fruits', items: ['apple', 'banana'] }, { name: 'Veggies', items: ['carrot', 'broccoli'] } ] } ) // →

Fruits

// //

Veggies

// ``` -------------------------------- ### Expression Syntax Examples Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Illustrates comparison, logical, grouping, property access, loop context, and parent context usage in expressions. ```typescript // Comparison {{#if age > 18}}Adult{{/if}} {{#if status == "active"}}Active{{/if}} // Logical operators {{#if age >= 18 && verified}}Access granted{{/if}} {{#if admin || moderator}}Elevated{{/if}} {{#if !banned}}Welcome{{/if}} // Grouping {{#if (age > 18) && (status == "verified")}} Full access {{/if}} // Property access {{#if user.role == "admin"}}Admin panel{{/if}} {{#if user.settings.notifications.email}} Email notifications enabled {{/if}} // Loop context {{#each items}} {{#if @index > 0}}, {{/if}}{{this}} {{/each}} // Prints items separated by commas // Parent context {{#each groups}} {{#each items}} {{#if @index == 0}}First: {{/if}}{{this}} {{/each}} {{/each}} ``` -------------------------------- ### Custom helpers Source: https://github.com/nds-stack/bun-html/blob/main/README.md Example of defining and using a custom helper function. ```typescript render('{{uppercase}}', { name: 'hello' }, { helpers: { uppercase(this: unknown) { return String(this).toUpperCase() }, }, }) ``` -------------------------------- ### Pipe/filter syntax example Source: https://github.com/nds-stack/bun-html/blob/main/README.md Demonstrates how to use pipe/filter syntax to transform values through helpers, including custom helpers. ```ts render('{{name | uppercase | truncate:5}}', { name: 'hello world' }, { helpers: { uppercase(this: unknown) { return String(this).toUpperCase() }, truncate(this: unknown, len: number) { return String(this).slice(0, len) }, }, }) // → 'HELLO' ``` -------------------------------- ### Iteration Example: Object Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Demonstrates looping over object properties using the {{#each}} helper, accessing the key and value. ```typescript render( '\n
\n {{#each person}}\n
{{@key}}
\n
{{this}}
\n {{/each}}\n
\n', { person: { name: 'Alice', age: '30', city: 'Portland' } } ) // →
//
name
Alice
//
age
30
//
city
Portland
//
``` -------------------------------- ### Unknown Tag Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Demonstrates an unknown tag error. ```typescript render('{{#invalid expr}}content{{/invalid}}', {}) // → Error: Unknown tag: #invalid expr ``` -------------------------------- ### Comments: {{! comment }} Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Shows how to use {{! comment }} to add comments that are stripped from the output. ```typescript render( 'Hello {{! name is variable }} {{name}}!', { name: 'World' } ) // → 'Hello World!' ``` -------------------------------- ### Plugins - beforeRender Source: https://github.com/nds-stack/bun-html/blob/main/README.md Example of a plugin that can modify the template or data before rendering. ```typescript const plugin = { name: 'inject', helpers: { greet() { return 'Hi' } }, beforeRender(tpl: string, data: Record) { return { template: tpl, data: { ...data, extra: '!' } } }, } ``` -------------------------------- ### clearCache() Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/cache.md Demonstrates how to clear all caches (templates, compiled functions, and partials) using the clearCache() function. ```typescript import { render, clearCache } from '@nds-stack/bun-html' // Render with default caching const html1 = render('

{{title}}

', { title: 'Hello' }) // Clear all caches clearCache() // Next render re-parses and re-compiles const html2 = render('

{{title}}

', { title: 'Hello' }) ``` -------------------------------- ### With conditionals and loops Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/README.md Example demonstrating the use of conditionals and loops within templates. ```typescript const html = render( '\n \n', { items: [{name: 'A', active: true}, {name: 'B', active: false}] } ) ``` -------------------------------- ### Iteration Example: Array Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Demonstrates looping over an array using the {{#each}} helper, accessing the current item, index, and key. ```typescript render( '\n \n', { items: ['apple', 'banana', 'cherry'] } ) // → ``` -------------------------------- ### Helper Context Access Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/configuration.md Shows how a helper function can access properties from the data context using `this`. ```typescript render( '{{formatted}}', { value: 42, multiplier: 2 }, { helpers: { formatted(this: any) { return `${this.value} × ${this.multiplier} = ${this.value * this.multiplier}` } } } ) // → '42 × 2 = 84' ``` -------------------------------- ### Conditional Example: Negation Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Demonstrates using the negation operator (!) within an {{#if}} condition. ```typescript render( '{{#if !banned}}

You can comment

{{/if}}', { banned: false } ) // → '

You can comment

' ``` -------------------------------- ### Async rendering with partials Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/render.md Example of asynchronous rendering that loads partial templates from a directory. ```typescript const html = await render( '{{> header}}{{content}}{{> footer}}', { title: 'Home' }, { partialsDir: './partials' } ) // Loads ./partials/header.html and ./partials/footer.html via Bun.file() ``` -------------------------------- ### Inline partials Source: https://github.com/nds-stack/bun-html/blob/main/README.md Example of defining and using inline partials within a template. ```typescript render('{{#def "item"}}
  • {{name}}
  • {{/def}}{{#each items}}{{> item}}{{/each}}', { items: [{ name: 'A' }, { name: 'B' }], }) // → '
  • A
  • B
  • ' ``` -------------------------------- ### Clear All Caches Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/configuration.md Example of clearing all internal caches using the `clearCache` function. ```typescript import { clearCache, purgeTemplate } from '@nds-stack/bun-html' // Clear all caches clearCache() ``` -------------------------------- ### Disable auto-escape Source: https://github.com/nds-stack/bun-html/blob/main/README.md Example of how to disable automatic HTML escaping. ```typescript render(tpl, data, { autoescape: false }) ``` -------------------------------- ### Inverse Conditionals: {{#unless}} Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Demonstrates how to use the {{#unless}} helper to render content when a condition is falsy. ```typescript render( '{{#unless banned}}

    Welcome!

    {{/unless}}', { banned: false } ) // → '

    Welcome!

    ' render( '{{#unless banned}}

    Welcome!

    {{/unless}}', { banned: true } ) // → '' ``` -------------------------------- ### Tokenizing Expression Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/expression.md Shows how to tokenize an expression string into an array of expression tokens. ```typescript const tokens = tokenizeExpr('age >= 18 && active') // [ // { type: 'Identifier', value: 'age' }, // { type: 'Gte' }, // { type: 'Number', value: '18' }, // { type: 'And' }, // { type: 'Identifier', value: 'active' } // ] ``` -------------------------------- ### File Not Found / Read Error Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Demonstrates the error when a partial or layout file is missing or unreadable. ```typescript render('{{> missing}}', {}, { partialsDir: './templates' }) // → Error: ENOENT: no such file or directory, open './templates/missing.html' ``` -------------------------------- ### Disable caching Source: https://github.com/nds-stack/bun-html/blob/main/README.md Example of how to disable caching for a render call. ```typescript render(tpl, data, { cache: false }) ``` -------------------------------- ### Unclosed {{#with}} Block Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Demonstrates an unclosed {{#with}} block error during rendering. ```typescript render('{{#with user}}{{name}}', { user: { name: 'Alice' } }) // → Error: Unclosed {{#with}} ``` -------------------------------- ### Null-safe Variable Resolution Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Demonstrates how missing or null properties are resolved to an empty string without errors. ```typescript render('{{user.profile.name}}', { user: null }) // → '' (no error, renders empty) render('{{user.profile.name}}', { user: { profile: null } }) // → '' (no error) render('{{user.profile.name}}', { user: { profile: { name: 'Alice' } } }) // → 'Alice' ``` -------------------------------- ### Scoped Context: {{#with}} Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Illustrates changing the context (scope) for a block of content using {{#with}}. ```typescript render(`
    {{#with user}}

    {{name}}

    Email: {{email}}

    City: {{address.city}}

    {{/with}}
    `, { user: { name: 'Alice', email: 'alice@example.com', address: { city: 'Portland' } } } ) // →
    //

    Alice

    //

    Email: alice@example.com

    //

    City: Portland

    //
    ``` -------------------------------- ### Conditional Example: Logical Operators Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Shows how to use logical operators (&&) within {{#if}} conditions. ```typescript render( '{{#if user.active && user.verified}}

    Full access

    {{/if}}', { user: { active: true, verified: true } } ) // → '

    Full access

    ' ``` -------------------------------- ### Variable Interpolation Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Demonstrates basic variable interpolation and dot notation for accessing nested properties. ```typescript import { render } from '@nds-stack/bun-html' const html = render( '

    Hello {{name}}, you live in {{address.city}}

    ', { name: 'Alice', address: { city: 'Portland' } } ) // → '

    Hello Alice, you live in Portland

    ' ``` -------------------------------- ### Unclosed {{#each}} Block Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Demonstrates an unclosed {{#each}} block error during rendering. ```typescript render('{{#each items}}
  • {{this}}
  • ', { items: [] }) // → Error: Unclosed {{#each}} ``` -------------------------------- ### Unclosed {{#if}} Block Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Demonstrates an unclosed {{#if}} block error during rendering. ```typescript render('{{#if user}}

    Hello

    ', { user: true }) // → Error: Unclosed {{#if}} ``` -------------------------------- ### Conditional Example: Simple Condition Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Illustrates conditional rendering using {{#if}} with a simple boolean variable. ```typescript render( '{{#if show}}

    Visible

    {{else}}

    Hidden

    {{/if}}', { show: true } ) // → '

    Visible

    ' ``` -------------------------------- ### Unexpected {{/each}} Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Demonstrates an unexpected {{/each}} tag error during rendering. ```typescript render('
    {{/each}}
    ', {}) // → Error: Unexpected {{/each}} ``` -------------------------------- ### Raw (Unescaped) Variables Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Shows how to output a variable's value without HTML escaping, useful for trusted HTML content. ```typescript render( '
    {{{html_content}}}
    ', { html_content: 'Bold' } ) // → '
    Bold
    ' // vs. with auto-escape (default) render( '
    {{html_content}}
    ', { html_content: 'Bold' } ) // → '
    <strong>Bold</strong>
    ' ``` -------------------------------- ### Exported Types Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/README.md Example of importing exported types from the @nds-stack/bun-html library. ```typescript import type { // Configuration RenderOptions, // Internal/AST structures Token, ASTNode, ASTNodeText, ASTNodeVariable, ASTNodeRawVariable, ASTNodeEach, ASTNodeIf, ASTNodeUnless, ASTNodeWith, ASTNodePartial, ASTNodeLayout, // Expression types ExprNode, // Compiled template type CompiledTemplate, } from '@nds-stack/bun-html' ``` -------------------------------- ### Operator Precedence Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Shows how to use parentheses to override default operator precedence in expressions. ```typescript // equivalent to: a || (b && c)) {{#if a || b && c}} // different: (a || b) && c) {{#if (a || b) && c}} ``` -------------------------------- ### Whitespace control example 2 Source: https://github.com/nds-stack/bun-html/blob/main/README.md Shows stripping whitespace and newlines around a block using `{{~#each~}}` and `{{~/each~}}`. ```ts render('{{~#each items~}}\n {{this}}\n{{~/each~}}', { items: ['a', 'b'] }) // → 'ab' (newlines and indentation stripped) ``` -------------------------------- ### Expression Parsing and Evaluation Examples Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/expression.md Demonstrates various use cases for parsing and evaluating expressions, including simple conditions, property access, loop context, parent context, and logical operators. ```typescript import { parseExpression, evaluateExpr } from '@nds-stack/bun-html/expression.js' // Simple condition const expr1 = parseExpression('age > 18') const result1 = evaluateExpr(expr1, { age: 25 }) console.log(result1) // → true // Property access const expr2 = parseExpression('user.role == "admin"') const result2 = evaluateExpr(expr2, { user: { role: 'admin' } }) console.log(result2) // → true // Loop context const expr3 = parseExpression('@index > 0') const result3 = evaluateExpr(expr3, { }, 5, '5') // index = 5 console.log(result3) // → true // Parent context with stack const expr4 = parseExpression('../published') const result4 = evaluateExpr(expr4, { draft: true }, undefined, undefined, [{ published: true }]) console.log(result4) // → true // Logical operators const expr5 = parseExpression('age >= 18 && verified') const result5 = evaluateExpr(expr5, { age: 20, verified: true }) console.log(result5) // → true // Logical OR with short-circuit const expr6 = parseExpression('missing || fallback') const result6 = evaluateExpr(expr6, { fallback: 'default' }) console.log(result6) // → 'default' ``` -------------------------------- ### Try-catch with Express adapter Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Example of handling errors when using the Express adapter for rendering templates. ```typescript import { adapter } from '@nds-stack/bun-html' import express from 'express' const app = express() app.engine('html', adapter.express({ dir: './views' })) app.get('/', (req, res) => { res.render('index', { title: 'Home' }, (err, html) => { if (err) { console.error('Template error:', err) res.status(500).send('Template render failed') } else { res.send(html) } }) }) ``` -------------------------------- ### Parent context access example Source: https://github.com/nds-stack/bun-html/blob/main/README.md Illustrates how to access parent context variables using `../` notation within nested blocks. ```handlebars {{#each groups}} {{#each items}} {{../../title}} - {{../name}}: {{this}} {{/each}} {{/each}} ``` -------------------------------- ### Try-catch with render() Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Example of using a try-catch block to handle errors during template rendering with `render()`. ```typescript import { render } from '@nds-stack/bun-html' try { const html = await render(template, data, { partialsDir: './views' }) // Process html } catch (err) { if (err instanceof Error) { if (err.message.includes('Unclosed')) { console.error('Template syntax error:', err.message) } else if (err.message.includes('ENOENT')) { console.error('Missing template file:', err.message) } else { console.error('Render error:', err.message) } } } ``` -------------------------------- ### Fallback Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/parser.md Demonstrates the behavior when an invalid expression syntax falls back to variable lookup. ```html render('{{#if age > 18 && broken}}yes{{/if}}', { 'age > 18 && broken': true }) // Invalid expression syntax falls back to looking for variable named 'age > 18 && broken' // (which won't exist, so renders empty) ``` -------------------------------- ### Multiple template files Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/adapters.md Demonstrates loading and rendering multiple template files in Hono. ```typescript app.use('*', adapter.hono({ dir: './views' })) app.get('/profile', async (c) => { // Loads ./views/profile.html from disk const template = await Bun.file('./views/profile.html').text() const user = { name: 'Alice', bio: 'Engineer' } const html = await c.var.render(template, user) return c.html(html) }) ``` -------------------------------- ### Comments: {{! comment }} Usage Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/template-syntax.md Provides an example of using comments for documentation or disabling sections of template code. ```html
    {{! TODO: Remove this section after migration }} {{!

    {{legacy_content}}

    }}

    {{new_content}}

    ``` -------------------------------- ### Invalid Partial/Layout Name Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Illustrates errors caused by invalid characters in partial or layout names. ```typescript render('{{> ../../../etc/passwd}}', {}, { partialsDir: './templates' }) // → Error: Invalid partial/layout name: "../../../etc/passwd" render('{{#layout "main/layout"}}content{{/layout}}', {}, { partialsDir: './templates' }) // → Error: Invalid partial/layout name: "main/layout" ``` -------------------------------- ### Expression Parsing Errors Examples Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Examples of expression parsing errors, including mismatched parentheses and incomplete expressions. ```typescript // Mismatched parentheses render('{{#if (age > 18}}{{/if}}', {}) // → Error: Expected ParenClose, got ... ``` ```typescript // Incomplete expression render('{{#if age >}}{{/if}}', {}) // → Error: Unexpected end of expression ``` -------------------------------- ### Error Handling in Hono Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/adapters.md Example of how to catch and handle template rendering errors within a Hono route. ```typescript app.use('*', adapter.hono({ dir: './templates' })) app.get('/item/:id', async (c) => { try { const template = '{{> missing}}' // File doesn't exist const html = await c.var.render(template, {}) return c.html(html) } catch (err) { return c.text('Template error: ' + String(err), 500) } }) ``` -------------------------------- ### Complex Expression Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/parser.md Example of a complex expression with multiple operators and grouping, and its parsed AST representation. ```typescript // Complex: (a > 5) && (b < 10) || c // Parsed as: BinaryOp(||, BinaryOp(&&, ...), Identifier(c)) ``` -------------------------------- ### Partials Require partialsDir Option Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Demonstrates the error when partials are used without `partialsDir` and how to resolve it. ```typescript render('{{> header}}
    {{content}}
    ', {}) // → Error: Partials require partialsDir option render('{{> header}}
    {{content}}
    ', {}, { partialsDir: './templates' }) // → OK (async, returns Promise) ``` -------------------------------- ### Helper Function Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/configuration.md Demonstrates how to define and use custom helper functions within templates. Helpers are invoked when a variable is undefined and its name matches a helper key. The `this` context is bound to the data context. ```typescript import { render } from '@nds-stack/bun-html' const data = { name: 'alice' } const result = render( '

    {{greeting}}

    ', data, { helpers: { greeting(this: unknown) { const name = typeof this === 'object' && this !== null && 'name' in this ? (this as any).name : 'Guest' return `Hello, ${name}!` } } } ) // → '

    Hello, alice!

    ' ``` -------------------------------- ### Basic Hono integration Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/adapters.md Demonstrates how to register the Hono adapter and use the `render` function in a route. ```typescript import { Hono } from 'hono' import { adapter } from '@nds-stack/bun-html' const app = new Hono() // Register adapter app.use('*', adapter.hono({ dir: './templates' })) // Use render in routes app.get('/', (c) => { const html = c.var.render('

    {{title}}

    ', { title: 'Welcome' }) return c.html(html) }) export default app ``` -------------------------------- ### Try-catch with Hono adapter Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Example of how to implement a try-catch block within a Hono route when using the Bun HTML adapter for rendering. ```typescript import { Hono } from 'hono' import { adapter } from '@nds-stack/bun-html' const app = new Hono() app.use('*', adapter.hono({ dir: './views' })) app.get('/', async (c) => { try { const html = await c.var.render('

    {{title}}

    ', { title: 'Home' }) return c.html(html) } catch (err) { console.error('Render error:', err) return c.text('Internal Server Error', 500) } }) ``` -------------------------------- ### purgeTemplate() Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/cache.md Shows how to remove a specific template from both the template cache and compiled cache using purgeTemplate(). ```typescript import { render, purgeTemplate } from '@nds-stack/bun-html' const template = '

    {{title}}

    ' // First render caches the template render(template, { title: 'Hello' }) // Remove from cache const wasPresent = purgeTemplate(template) console.log(wasPresent) // → true // Next render re-parses and re-compiles render(template, { title: 'Hello' }) // Purge a template not in cache const missing = purgeTemplate('

    {{notCached}}

    ') console.log(missing) // → false ``` -------------------------------- ### Conditional Caching Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/cache.md Demonstrates how to disable caching for a single render or compile call by passing { cache: false } in RenderOptions. ```typescript import { render } from '@nds-stack/bun-html' // This call does not read from or write to cache const result = render(template, data, { cache: false }) ``` -------------------------------- ### If Block Processing Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/expression.md Illustrates the integration of expression parsing and evaluation within template rendering, specifically for 'if' blocks. ```typescript // Template const template = '{{#if user.age >= 18}}Adult{{/if}}' // Parse phase const ast = parse(tokenize(template)) // ast[0] = { // type: 'If', // expression: 'user.age >= 18', // exprAst: { type: 'BinaryOp', op: '>=', ... } // } // Render phase (async) const result = evaluateExpr(ast[0].exprAst, { user: { age: 25 } }) // → true, so children are rendered // Compile phase (sync) // Generated JS: if (__d?.["user"]?.["age"] >= 18) { ... } ``` -------------------------------- ### Express with layouts Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/adapters.md Demonstrates using the Express adapter with layouts for templating. ```typescript import { adapter } from '@nds-stack/bun-html' import Express from 'express' const app = Express() app.engine('html', adapter.express({ dir: './views' })) // Template: views/page.html // {{#layout "main"}} //

    {{title}}

    //

    {{body}}

    // {{/layout}} // Layout: views/main.html // // {{title}} // {{content}} // app.get('/', (req, res) => { res.render('page', { title: 'Home', body: 'Welcome' }) }) ``` -------------------------------- ### Async with partials Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/adapters.md Shows how to use asynchronous rendering with partials in Hono. ```typescript app.use('*', adapter.hono({ dir: './templates' })) app.get('/page', async (c) => { const html = await c.var.render( '{{> header}}
    {{content}}
    {{> footer}}', { content: 'Page content' } ) return c.html(html) }) ``` -------------------------------- ### Basic Express integration Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/adapters.md Integrates bun-html with an Express application, setting up the engine and rendering a basic route. ```typescript import Bun from 'bun' import Express from 'express' import { adapter } from '@nds-stack/bun-html' const app = Express() // Configure bun-html engine app.engine('html', adapter.express({ dir: './views' })) app.set('view engine', 'html') app.set('views', './views') // Render route app.get('/', (req, res) => { res.render('index', { title: 'Home', name: 'Alice' }) // Loads ./views/index.html and renders with provided data }) app.listen(3000) ``` -------------------------------- ### Async with partials Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/README.md Demonstrates how to use async rendering with partials in bun-html. ```typescript const html = await render( '{{> header}}
    {{content}}
    {{> footer}}', { content: 'Page' }, { partialsDir: './templates' } ) ``` -------------------------------- ### Precompile CLI Source: https://github.com/nds-stack/bun-html/blob/main/README.md Command to precompile HTML templates using the CLI. ```bash bun-html compile ./views --out ./dist/views ``` -------------------------------- ### Hono with cached template strings Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/adapters.md Shows how to use the Hono adapter with pre-defined template strings for efficient rendering. ```typescript import { Hono } from 'hono' import { adapter } from '@nds-stack/bun-html' const app = new Hono() app.use('*', adapter.hono()) const templates = { card: '

    {{name}}

    {{desc}}

    ', list: '' } app.get('/card', (c) => { const html = c.var.render(templates.card, { name: 'Product', desc: 'Great item' }) return c.html(html) }) ``` -------------------------------- ### Unexpected Character in Expression Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Demonstrates an unexpected character error during expression parsing. ```typescript render('{{#if age $$ 18}}adult{{/if}}', { age: 20 }) // → Error: Unexpected character '$' in expression ``` -------------------------------- ### Custom helpers Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/api-reference/render.md Shows how to define and use custom helper functions within templates. ```typescript const html = render( '

    {{uppercase}}

    ', { text: 'hello' }, { helpers: { uppercase(this: unknown) { return String(this).toUpperCase() } } } ) // → '

    HELLO

    ' ``` -------------------------------- ### Partials Not Supported in Sync Compilation Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Shows how using partials with `compileToFunction` results in an error. ```typescript import { compile, compileToFunction } from '@nds-stack/bun-html' const ast = compile('{{> header}}content{{> footer}}') const fn = compileToFunction(ast) fn({}, undefined, Bun.escapeHTML) // → Error: Partials require partialsDir option ``` -------------------------------- ### Layouts Require partialsDir Option Example Source: https://github.com/nds-stack/bun-html/blob/main/_autodocs/errors.md Shows the error when layouts are used without `partialsDir`. ```typescript render('{{#layout "main"}}content{{/layout}}', {}) // → Error: Layouts require partialsDir option ```