Technically it's a "yesterday I learned" kind of post
This commit is contained in:
parent
d7ec4ef0a5
commit
88d0bb395d
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Accessing Handlebars variables in an outer scope"
|
||||
tags:
|
||||
- rust
|
||||
---
|
||||
|
||||
This weekend I learned some unfamiliar behaviors with the way Handlebars
|
||||
handles nested variable scopes. I typically use Handlebars via the
|
||||
[handlebars-rust](https://github.com/sunng87/handlebars-rust) implementation
|
||||
which aims to maintain nearly one to one compatibility with the [JavaScript
|
||||
implementation](https://handlebarsjs.com/). They have block scope helpers such
|
||||
as `#each` and `#with`, both of which create an inner scope for variable
|
||||
resolution. Unfortunately, the syntax can be quite unintuitive for accessing outer
|
||||
scope once in those nested scopes.
|
||||
|
||||
Handlebars is a largely declarative templating syntax which uses curlybraces
|
||||
such as `{{var}}` for variable and helper substitution. The `#each` helper is
|
||||
important for loops, imagine the following data structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"repos" : [
|
||||
{
|
||||
"name" : "otto"
|
||||
},
|
||||
{
|
||||
"name" : "l4bsd"
|
||||
}
|
||||
],
|
||||
"mood" : "cool"
|
||||
}
|
||||
```
|
||||
|
||||
This could be rendered into a list on a page via:
|
||||
|
||||
```html
|
||||
<ul>{% raw %}
|
||||
{{#each data.repos}}
|
||||
<li>\{{name}}</li>
|
||||
{{/each}}{% endraw %}
|
||||
</ul>
|
||||
```
|
||||
|
||||
Inside the `#each` block the values of the indexed object become the scope for variable resolution, such that `{{name}}` actually refers to `data.repos[i].name`. This presents problems when the template must refer to outer scope variables, such as `mood`. In the Rust implementation this variable resolution can be accomplished through a path traversal style syntax such as:
|
||||
|
||||
```html
|
||||
<ul>{% raw %}
|
||||
{{#each data.repos}}
|
||||
<li>\{{name}} is {{../data.mood}}</li>
|
||||
{{/each}}{% endraw %}
|
||||
</ul>
|
||||
```
|
||||
|
||||
The `../data.mood` is all that's needed to refer to the variable in the outer
|
||||
scope of variables. Not what I expected at all, and the only reason I found it
|
||||
was because I found [an old
|
||||
issue](https://github.com/sunng87/handlebars-rust/issues/416) which alluded to
|
||||
the syntax and gave it a try.
|
||||
|
||||
|
Loading…
Reference in New Issue