Skip to content
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

Nested partials not working #1218

Closed
pmendelski opened this issue May 8, 2016 · 5 comments · Fixed by #1243
Closed

Nested partials not working #1218

pmendelski opened this issue May 8, 2016 · 5 comments · Fixed by #1243

Comments

@pmendelski
Copy link

Nested partials cause RangeError.
Example: https://jsfiddle.net/mendlik/bp7jsbd8/3/

This problem is probably a root cause for another issue #1185

@damncabbage
Copy link

Confirmed; c.f. #1185 (comment)

@lawnsea
Copy link
Collaborator

lawnsea commented Jul 30, 2016

I am investigating this rn. What I've found thus far is that this line is the source of the infinite recursion: https://github.com/wycats/handlebars.js/blob/master/lib/handlebars/runtime.js#L48.

@lawnsea
Copy link
Collaborator

lawnsea commented Aug 1, 2016

Ok, I did a lot of stepping through this code this weekend and root-caused the bug to this line: https://github.com/wycats/handlebars.js/blob/master/lib/handlebars/runtime.js#L218. I'm not sure what should happen, but what does happen is that the options.fn value for the outer partial is overwritten by the options.fn value for the nested partial.

I tried to figure out what's going on, but was unable to do so. I think we're going to need @kpdecker's help on this one.

Minimal repro script runnable from the root of repo

'use strict';

const Handlebars = require('./dist/handlebars.js');

const nested = `
nested
{{>@partial-block}}
nested-end
`;

const outer = `
outer
{{#>nested}}
  {{>@partial-block}}
{{/nested}}
outer-end
`;

const template = `
{{#>outer}}
content
{{/outer}}
`;

Handlebars.registerPartial('outer', outer);
Handlebars.registerPartial('nested', nested);

var compiledTemplate = Handlebars.compile(template);
console.log('result:\n', compiledTemplate());

@cappslock
Copy link

@kpdecker 👋 sup

@kpdecker
Copy link
Collaborator

kpdecker commented Aug 3, 2016

I have not really been active in Handlebars for a while and just started a new job that is JSX focused rather than Handlebars, so I don't expect to have much time to work on this in the near future. @wycats may be able to tap someone in the Ember community to help out in my absence.

lawnsea added a commit to lawnsea/handlebars.js that referenced this issue Aug 16, 2016
The root cause of handlebars-lang#1218 is that `invokePartial` creates a stack of data frames
for nested partial blocks, but `resolvePartial` always uses the value at top of
the stack without "popping" it. The result is an infinite recursive loop, as
references to `@partial-block` in the partial at the top of the stack resolve to
itself.

So, walk up the stack of data frames when evaluating. This is accomplished by
1) setting the `partial-block` property to `noop` after use and
2) using `_parent['partial-block']` if `partial-block` is `noop`

Fix handlebars-lang#1218
lawnsea added a commit to lawnsea/handlebars.js that referenced this issue Nov 9, 2016
The root cause of handlebars-lang#1218 is that `invokePartial` creates a stack of data frames
for nested partial blocks, but `resolvePartial` always uses the value at top of
the stack without "popping" it. The result is an infinite recursive loop, as
references to `@partial-block` in the partial at the top of the stack resolve to
itself.

So, walk up the stack of data frames when evaluating. This is accomplished by
1) setting the `partial-block` property to `noop` after use and
2) using `_parent['partial-block']` if `partial-block` is `noop`

Fix handlebars-lang#1218
lawnsea added a commit that referenced this issue Nov 11, 2016
The root cause of #1218 is that `invokePartial` creates a stack of data frames
for nested partial blocks, but `resolvePartial` always uses the value at top of
the stack without "popping" it. The result is an infinite recursive loop, as
references to `@partial-block` in the partial at the top of the stack resolve to
itself.

So, walk up the stack of data frames when evaluating. This is accomplished by
1) setting the `partial-block` property to `noop` after use and
2) using `_parent['partial-block']` if `partial-block` is `noop`

Fix #1218
nknapp pushed a commit that referenced this issue Mar 9, 2017
The root cause of #1218 is that `invokePartial` creates a stack of data frames
for nested partial blocks, but `resolvePartial` always uses the value at top of
the stack without "popping" it. The result is an infinite recursive loop, as
references to `@partial-block` in the partial at the top of the stack resolve to
itself.

So, walk up the stack of data frames when evaluating. This is accomplished by
1) setting the `partial-block` property to `noop` after use and
2) using `_parent['partial-block']` if `partial-block` is `noop`

Fix #1218
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants