Skip to content

1.0.0 AST Compiler

Choose a tag to compare

@theodorejb theodorejb released this 23 Mar 04:20
· 45 commits to master since this release

Rewrote the parser and compiler to use an abstract syntax tree, based on the same lexical analysis and grammar specification as Handlebars.js. This eliminates a large class of edge cases and parsing bugs that the old regex-based approach failed to handle correctly.

This release is 35-40% faster than v0.9.9 and LightnCandy at compiling and executing complex templates, and uses almost 30% less memory. The code is also significantly simpler and easier to maintain.

Added

  • Support for nested inline partials.
  • Support for closures in data and helper arguments.
  • helperMissing and blockHelperMissing hooks: handle calls to unknown helpers with the same API as in Handlebars.js, replacing the old helperResolver option.
  • knownHelpers compile option: tell the compiler which helpers will be available at runtime for more efficient execution (helper existence checks can be skipped).
  • assumeObjects compile option: a subset of strict mode that generates optimized templates when the data inputs are known to be safe.
  • Support for deprecated {{person/firstname}} path expressions for parity with Handlebars.js (avoid using this syntax in new code, though).

Changed

  • Custom helpers must now be passed at runtime when invoking a template (via the helpers runtime option key), rather than via the Options object passed to compile or precompile. This is a significant optimization, since it eliminates the overhead of reading and tokenizing PHP files to extract helper functions. It also enables sharing helper closures across multiple templates and renders, and removes limitations on what they can access and do (e.g. it resolves zordius/lightncandy#342).
  • Exceptions thrown by custom helpers are no longer caught and re-thrown, so the original exception can now be caught in your own code for easier debugging (#13).
  • The partialResolver closure signature no longer receives an internal Context argument. Now only the partial name is passed.
  • knownHelpersOnly now works as in Handlebars.js, and an exception will be thrown if the template uses a helper which is not in the knownHelpers list.
  • Updated various error messages to align with those output by Handlebars.js.

Removed

  • Options::$helpers: instead pass custom helpers when invoking a template, using the helpers key in the runtime options array (the second argument to the template closure).
  • Options::$helperResolver: use the helperMissing / blockHelperMissing runtime helpers instead.

Fixed

  • Fatal error with deeply nested else if using custom helper (#2).
  • Incorrect rendering of float values (#11).
  • Conditional @partial-block expressions.
  • Support for @partial-block in nested partials (zordius/lightncandy#292).
  • Ability to precompile partials and pass them at runtime (zordius/lightncandy#341).
  • Fatal error when a string parameter to a partial includes curly braces (zordius/lightncandy#316).
  • Behavior when modifying root context in a custom helper (zordius/lightncandy#350).
  • Escaping of block params and partial names.
  • Inline partials defined inside a {{#with}} or other block leaking out of that block's scope after it closes.
  • Numerous other bugs related to scoping, block params, inverted block helpers, section iteration, and depth-relative paths.