You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
| LightnCandy 1.2.6 | 5.2 ms | 2.8 ms | 8.0 ms | 5.3 MB |
13
-
| PHP Handlebars 1.0| 3.5 ms | 1.6 ms | 5.1 ms | 3.6 MB |
13
+
| PHP Handlebars 1.1| 3.5 ms | 1.6 ms | 5.1 ms | 3.6 MB |
14
14
15
15
_Tested on PHP 8.5 with the JIT enabled. See the `benchmark` branch to run the same test._
16
16
17
17
## Features
18
18
19
19
* Supports all Handlebars syntax and language features, including expressions, subexpressions, helpers,
20
-
partials, hooks, and `@data` variables.
20
+
partials, hooks, `@data` variables, whitespace control, and `.length` on arrays.
21
21
* Templates are parsed using [PHP Handlebars Parser](https://github.com/devtheorem/php-handlebars-parser),
22
22
which implements the same lexical analysis and AST grammar specification as Handlebars.js.
23
23
* Tested against the full [Handlebars.js spec](https://github.com/jbboehr/handlebars-spec).
@@ -70,67 +70,116 @@ echo $template(['first' => 'John']); // Error: "last" not defined
70
70
71
71
### Available Options
72
72
73
-
*`knownHelpers`: Associative array (`helperName => bool`) of helpers known to exist at template execution time.
74
-
Passing this allows the compiler to optimize a number of cases.
75
-
Builtin helpers are automatically included in this list and may be omitted by setting that value to `false`.
76
-
*`knownHelpersOnly`: Enable to allow further optimizations based on the known helpers list.
77
-
*`noEscape`: Enable to not HTML escape any content.
73
+
*`knownHelpers`: Associative array (`helperName => bool`) of helpers that will be registered at runtime.
74
+
The compiler uses this to emit direct helper calls instead of dynamic dispatch, which is faster and required when `knownHelpersOnly` is set.
75
+
Built-in helpers (`if`, `unless`, `each`, `with`, `lookup`, `log`) are pre-populated as `true` and may be excluded by setting them to `false`.
76
+
Setting `if` or `unless` to `false` also disables the inline ternary optimization and allows those helpers to be overridden at runtime.
77
+
78
+
*`knownHelpersOnly`: Restricts templates to only the helpers in `knownHelpers`, enabling further compile-time optimizations:
79
+
block sections and bare `{{identifier}}` expressions skip the runtime helper table and use a direct context lookup,
80
+
and any use of an unregistered helper throws a compile-time exception instead of falling back to dynamic dispatch.
81
+
82
+
*`noEscape`: Set to `true` to disable HTML escaping of output.
83
+
78
84
*`strict`: Run in strict mode. In this mode, templates will throw rather than silently ignore missing fields.
79
85
This has the side effect of disabling inverse operations such as `{{^foo}}{{/foo}}`
80
86
unless fields are explicitly included in the source object.
81
-
*`assumeObjects`: Removes object existence checks when traversing paths.
82
-
This is a subset of strict mode that generates optimized templates when the data inputs are known to be safe.
83
-
*`preventIndent`: Prevent indented partial-call from indenting the entire partial output by the same amount.
87
+
88
+
*`assumeObjects`: A looser alternative to `strict` mode. A null intermediate in a path
89
+
(e.g. `foo` is null when resolving `foo.bar`) throws an exception, but a missing terminal key returns null silently.
90
+
91
+
*`preventIndent`: Prevents an indented partial call from indenting the entire partial output by the same amount.
92
+
84
93
*`ignoreStandalone`: Disables standalone tag removal.
85
94
When set, blocks and partials that are on their own line will not remove the whitespace on that line.
95
+
86
96
*`explicitPartialContext`: Disables implicit context for partials.
87
97
When enabled, partials that are not passed a context value will execute against an empty object.
88
-
*`partials`: Provide a `name => value` array of custom partial template strings.
89
-
*`partialResolver`: A closure which will be called for any partial not in the `partials` array to return a template for it.
98
+
99
+
*`partials`: An associative array of custom partial template strings (`name => template`).
100
+
101
+
*`partialResolver`: A closure that will be called at compile time for any partial not found in the `partials` array,
102
+
and should return a template string for it.
90
103
91
104
## Runtime Options
92
105
93
106
`Handlebars::compile` returns a closure which can be invoked as `$template($context, $options)`.
94
107
The `$options` parameter takes an array of runtime options, accepting the following keys:
95
108
96
-
*`data`: An array to define custom `@variable` private variables.
97
-
*`helpers`: An `array<string, \Closure>` containing custom helpers to add to the built-in helpers.
98
-
*`partials`: An `array<string, \Closure>` containing partial functions precompiled with `Handlebars::compile`.
99
-
This is useful if multiple templates sharing the same partials need to be compiled and rendered, and you don't want
100
-
to recompile the same partials over and over for each template.
109
+
*`data`: An associative array of initial `@data` variables (e.g. `['version' => '1.0']` makes `@version` available in the template).
110
+
111
+
*`helpers`: An `array<string, \Closure>` of helpers to merge with the built-in helpers. Can also be used to override a built-in helper by using the same name.
112
+
113
+
*`partials`: An `array<string, \Closure>` of partial closures precompiled with `Handlebars::compile`.
114
+
Useful when multiple templates share the same partials, and you want to avoid recompiling them for each template.
101
115
102
116
## Custom Helpers
103
117
104
118
Helper functions will be passed any arguments provided to the helper in the template.
105
119
If needed, a final `$options` parameter can be included which will be passed a `HelperOptions` instance.
106
-
This object contains properties for accessing `hash` arguments, `data`, and the current `scope`, `name`,
107
-
as well as `fn()` and `inverse()` methods to render the block and else contents, respectively.
108
120
109
121
For example, a custom `#equals` helper with JS equality semantics could be implemented as follows:
110
122
111
123
```php
112
124
use DevTheorem\Handlebars\{Handlebars, HelperOptions};
113
125
114
126
$template = Handlebars::compile('{{#equals my_var false}}Equal to false{{else}}Not equal{{/equals}}');
115
-
$options = [
116
-
'helpers' => [
117
-
'equals' => function (mixed $a, mixed $b, HelperOptions $options) {
118
-
// In JS, null is not equal to blank string or false or zero,
119
-
// and when both operands are strings no coercion is performed.
@@ -176,7 +224,7 @@ using the `Handlebars::escapeExpression()` method to avoid potential security co
176
224
177
225
## Missing Features
178
226
179
-
All syntax and language features from Handlebars.js 4.7.8 should work the same in PHP Handlebars,
227
+
All syntax and language features from Handlebars.js 4.7.9 should work the same in PHP Handlebars,
180
228
with the following exceptions:
181
229
182
230
* Custom Decorators have not been implemented, as they are [deprecated in Handlebars.js](https://github.com/handlebars-lang/handlebars.js/blob/master/docs/decorators-api.md).
0 commit comments