-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conditionals affect ../
path segment behaviour in blocks
#1028
Comments
Each block creates a context. So basically every time you do We choose to have the simple rule above as it's easier to reason about from the static source code, both for the compiler and the programmer, assuming they are aware of the rule. This is not the first time similar concerns have been raised, I'm just not sure if the cost of breaking changes and performance impact is less than the conceptual overhead that users have to be aware of for this rule. |
That makes sense in and of itself, because some, but not every So I can see how the rule makes sense, however there are two problems with it: First: the behaviour is inconsistent - if what you're saying is true, then surely my very first example should be:
Or is that what you're referring to about Secondly, the documentation on handlebarsjs.com is either wrong, or using very confusing language:
It seems to me that I am interpreting 'parent template scope' to mean the root of the JSON object associated with the template you're currently working in. The way I'm reading that documentation is that |
One way to think about it is that this is an array, literally If you had something like:
The inner most block would be executing against depths stack of something like: So I agree that the documentation you cited is quite confusing. It would be more accurate to say that it references the parent block rather than parent template but I don't know if that's any clearer to a user who is not familiar with the innards of the library. I can try to fix although clear accessible documentation is not always my strong suit :) |
i'd like to cast my vote for #if not changing context. i understand why its this way, etc. but i think the naive assumption about how it works would be preferred. |
I'm thinking along the same lines. I'm loathe to say it because I fully understand what a pain in the ass it will be to change, but really - I think the behaviour here is wrong. @kpdecker your last explanation made the what and why make 100% sense to me. Thanks for taking the time to do that, I really appreciate it. Still even from just the perspective of documenting this - it's nigh impossible to explain without giving away the internals, which is a huge indicator that the behaviour is not ideal. Handlebars' power lies in that it is so intuitive - 99.9% of the time it just works in that it does exactly what you expect it to do. That means that when you find the 0.1% where it trips you up and does something unexpected, the learning curve is enormously steep because there was no learning required at all in order to start using it. That makes me in favour of moving that 0.1% as far away from standard use cases as possible. Therefore, I'd suggest that at the very least #if and #unless be treated as special cases that do not increase depth. Being able to make the same thing happen with custom block helpers would be a nice to have, but it's still a use case which is significantly further from the average user than I suppose that the real solution is to have a more intelligent data structure for handling depth? I'd need to look at the code more closely. I'm very much up for helping out if this change gets the go-ahead. If not, I'd also be willing to have a go at documenting it more clearly. I'm not great at docs either but maybe my being an outsider will help. |
On the surface, the technical side of supporting something like this across the board is not much:
And it should work relatively transparently. There are two downsides to this:
Basically the implementation right now is using an initially surprising rule that is consistent at all times, I really do like the "friendlier" solution but am having trouble getting over the risk factors above. |
I have been thinking about this, and have a couple of points to add:
I'd suggest that this is no worse than the current implementation. At the moment the behaviour of Another way to look at it is that if I specify All of this being said, I have absolutely no idea how I'd manage this change in Ghost themes, it's going to cause absolute havoc for sure! |
I recently used Basically we would make the push operations for depths conditional and it would only occur if the context changes, following my comment above. For the upgrade path, this is something that is grepable and in theory has less use than other things so it might not be that painful. Regardless we should have a flag that allows the user to choose. (We could implement this behind a flag without a major change and then switch the default value's meaning in the next major release but I'm not sure that that is worth the overhead since we try to avoid major releases and that could be a ways off) |
Just for interest's sake, the thing that made me raise this originally, was I wanted to do some work to make 'Casper', the default theme for Ghost, more consistent. I wanted to change this block in the tag template to be a However, because of the if statement in the tag template, the snippet: The upgrade path is difficult, of course. I think if there's going to be a flag to switch the behaviour for a version, then that is going to help to smooth the transition. Given that the behaviour is both unintuitive according to normal I was wondering, if it is implemented such that too many E.g. in my case I want to go back to the template root (which is what the documentation suggests a single |
👍 for the breaking but IMHO more intuitive change. this has bitten me a few times as a new Handlebarser. i think @ErisDS hit it on the head
thanks for posting and considering. |
@ErisDS
I don't want to go down the route where people start trying to throw in an arbitrary number of This is now implemented in master and I'd appreciate if the interested parties could take a look and give me a sense of how painful their own implementations are. When I write the release notes, I plan on saying that the migration path involves checking all use of |
Creating a new depth value seems to confuse users as they don’t expect things like `if` to require multiple `..` to break out of. With the change, we avoid pushing a context to the depth list if it’s already on the top of the stack, effectively removing cases where `.` and `..` are the same object and multiple `..` references are required. This is a breaking change and all templates that utilize `..` will have to check their usage and confirm that this does not break desired behavior. Helper authors now need to take care to return the same context value whenever it is conceptually the same and to avoid behaviors that may execute children under the current context in some situations and under different contexts under other situations. Fixes handlebars-lang#1028
handlebars.js 4.0.0 changed the depth behaviour when using the if and unless conditionals - handlebars-lang/handlebars.js#1028 This commit changes the handlebars.php helpers to match.
Fixed advanced filters to work with handlebars v4. (handlebars-lang/handlebars.js#1028)
I'm not sure if this is a bug or not, but it seems very unexpected:
At the top level of the context tree, assuming an object a bit like
{a: 1, b: 2}
It is expected that
{{b}}
would become2
.However, when inside the scope of an object and using
../
path segments to reference the parent template, things get a bit weird if you also add a conditional into the mix:Assume an object like
{a: {b: true}, c: 'd'}
I would expect the two items above to both output the same... however in order to output
c
, it requires two../
segments - which I don't understand :(Did I find a bug or am I missing something?
Fiddle with the above examples in detail: http://jsfiddle.net/ErisDS/618njbng/
The text was updated successfully, but these errors were encountered: