Handlebars.Net Documentation

repository·master·Indexed 23 days ago

https://github.com/handlebars-net/handlebars.net

A high-performance .NET implementation of Handlebars.js templates that compiles templates directly to IL bytecode. It supports custom helpers, partials, decorators, and value formatters. The library includes extensions for System.Text.Json and Newtonsoft.Json, as well as a wide range of built-in helpers. Key features include whitespace control, HTML escaping, and a shared environment to reduce memory footprint.

Tokens
6.8K
Snippets
16
Records
42
Agent score
31%

What's inside Handlebars.Net

  1. Available Handlebars.Net Extensions

    master

    Handlebars.Net can be extended with additional support for JSON formats and extra helpers through these projects:

    • Handlebars.Net.Extension.Json: Adds support for System.Text.Json.JsonDocument.
    • Handlebars.Net.Extension.NewtonsoftJson: Adds support for Newtonsoft.Json.
    • Handlebars.Net.Helpers: Provides a wide range of additional helpers in categories such as 'Constants', 'Enumerable', 'Math', 'Regex', 'String', 'DateTime', 'Url', 'DynamicLinq', 'Humanizer', 'Json', 'Random', 'Xeger', and 'XPath'.
  2. How to control whitespace

    master

    Handlebars provides whitespace control characters (~) to strip whitespace around tags.

    Whitespace Control Characters:

    • {{~ (Strip Left): Removes all whitespace to the left of the tag.
    • ~}} (Strip Right): Removes all whitespace to the right of the tag.
    • {{~ and ~}} (Strip Both): Removes whitespace on both sides.

    Scope of Stripping:

    • Works on standard tags, block helper open/close tags ({{#if ...~}}, {{~/if}}), {{else}}, comments, and partials.
    • Standalone Tags: If a tag (like a block helper or comment) is the only non-whitespace content on a line, it will strip the entire line, including the newline character.
    Hello, {{~name}} !
    {{name~}}
    {{~name~}}
    {{#if cond~}}
      B
    {{~/if}}
  3. Define and use inline partials

    master

    Inline partials are defined within the template using {{#*inline "name"}}...{{/inline}}. They are scoped to the block they are defined in and cannot be accessed outside that scope. Inline partials take priority over registered partials of the same name.

    {{#*inline "myPartial"}}Hello {{name}}!{{/inline}}{{> myPartial}}
    
    // Scoped inline partial (will throw error if accessed outside the block)
    {{#if true}}{{#*inline "p"}}scoped{{/inline}}{{/if}}{{> p}}
  4. How to use nested paths and dot notation

    master

    You can access nested object properties using dot notation.

    Key Behaviors:

    • Nesting: {{person.name}} accesses data.person.name.
    • Deep Nesting: {{a.b.c}} accesses data.a.b.c.
    • Null Intermediates: If an intermediate property in a path is null (e.g., {{person.name}} where person is null), it renders an empty string without throwing an error.
    • Numeric Indices: You can access array elements using dot notation with an index: {{list.0}} retrieves the first element of list.
    • Hyphenated Keys: Properties with hyphens like foo-bar can be accessed via {{foo-bar}}.
    {{person.name}}
    {{a.b.c}}
    {{list.0}}
    {{foo-bar}}
  5. Handle boolean string rendering differences

    master

    In Handlebars.Net, rendering a boolean value via {{val}} results in .NET's default string representation. This means true renders as "True" and false renders as "False" (capitalized), whereas the canonical Handlebars.js spec expects lowercase "true" and "false".

    Note: This only affects the string output. Boolean values are still correctly treated as falsy/truthy by logic helpers like {{#if}}.

  6. How HTML escaping and unescaped output work

    master

    By default, Handlebars escapes HTML characters to prevent XSS.

    Escaping Rules:

    • Standard {{expr}} escapes: &, <, >, ", ', `, and =.
    • Example: <b becomes &lt;b.

    Unescaped Output:

    • Triple-Stash {{{expr}}}: Renders the value without any HTML escaping.
    • Ampersand {{& expr}}: Identical in behavior to triple-stash; renders unescaped output.
    • SafeString: If a helper returns a SafeString object, {{helper}} will render it without double-encoding.

    Note: Data values containing {{ are treated as literal text and are never re-evaluated as Handlebars expressions.

  7. Performance Considerations for Compilation and Rendering

    master

    Compilation

    Compilation is an intensive process. It is highly recommended to compile once and cache the resulting function to be reused throughout the life of your process.

    Rendering

    Rendering performance depends heavily on the model type used. The time spent is primarily in resolving values against the model.

    Model TypePerformanceNotes
    IDictionary<string, object>Fastest (microseconds)Highly optimized
    POCOFast (milliseconds)Uses reflection
    Dynamic ObjectsSlower (tens of ms)
    Custom Type Implementations (e.g. ICustomTypeDescriptor)Slowest (hundreds of ms+)Not optimized for heavy reflection
  8. How to use segment-literal paths for special keys

    master

    When keys contain spaces, dots, or other special characters, use square brackets [] to define a segment literal.

    Syntax Options:

    • Keys with spaces: {{[foo bar]}}
    • Keys with dots: {{[foo.bar]}}
    • Nested segment literals: {{obj.[a b]}}
    • Array index via brackets: {{list.[0]}}
    • Double-quote string literals: {{"foo bar"}} (a variant of bracket notation).
    • Keys starting with [: {{[[startsWithBracket]}}
    {{[foo bar]}}
    {{[foo.bar]}}
    {{obj.[a b]}}
    {{list.[0]}}
    {{"foo bar"}}