twig.js
twig.js copied to clipboard
Crashes on including a template twice that embeds another template
I have some complex twig templating from a php twig project that crashes in twig js. Here is the minimum code required to trigger the crash:
const Twig = require('twig');
const twig = Twig.twig;
twig({
id: 'poc2',
allowInlineIncludes: true,
data: ``
});
twig({
id: 'poc1',
allowInlineIncludes: true,
data: `
{% embed 'poc2' %}{% endembed %}
`
});
const poc = twig({
id: 'poc',
allowInlineIncludes: true,
data: `
{% include 'poc1' %}
{% include 'poc1' %}
`
});
console.log(poc.render());
And here is the error message:
Error parsing twig template undefined:
TwigException: Cannot extend an inline template.
I'm going to try to fix it and submit a PR, but if someone knows a solution or one is already in the works please let me know.
Thanks!
Seems like when the embed override template is created it clobbers the original template's id in the template registry (https://github.com/twigjs/twig.js/blob/master/src/twig.logic.js#L1184), which would definitely cause problems when you're only using ids and not file paths or urls... still digging.
const embedOverrideTemplate = new Twig.Template({
data: token.output,
id: state.template.id,
base: state.template.base,
path: state.template.path,
url: state.template.url,
name: state.template.name,
method: state.template.method,
options: state.template.options
});
I've confirmed that changing the id like:
const embedOverrideTemplate = new Twig.Template({
data: token.output,
id: state.template.id + 'e',
base: state.template.base,
path: state.template.path,
url: state.template.url,
name: state.template.name,
method: state.template.method,
options: state.template.options
});
results in no error, but I doubt it would result in the right output
I tried to break it but it seems to just work
const Twig = require('twig');
const twig = Twig.twig;
twig({
id: 'poc2',
allowInlineIncludes: true,
data: `hello{% block j %}{% endblock %}\n`
});
twig({
id: 'poc1',
allowInlineIncludes: true,
data: `
{% embed 'poc2' %}{% block j %}{{ b }}{% endblock %}{% endembed %}
`
});
const poc = twig({
id: 'poc',
allowInlineIncludes: true,
data: `
{% include 'poc1' with { b: 'a' } %}
{% include 'poc1' with { b: 'b' } %}
`
});
console.log(poc.render());
I'm going to fork and use my fork for now, since this solution is a hack, but seems to fit my needs. Hopefully someone who knows more about the intended structure of twigjs can propose a better solution.
(here's the fork: https://github.com/JamesB797/twig.js)
I actually have a similar problem and @JamesB797 hack seemed to fix my problem too. Would be nice to have a real fix though...
We were having an issue with nested embeds on a recent project and this above fixed it as well. Basically anything like this would throw an error:
FILE_1.twig (works)
{% embed "WHATEVER.twig" %}
...
{% endembed %}
FILE_2.twig (breaks)
{% embed "FILE_1.twig" %}
...
{% endembed %}
@RobLoach we are investing in this project at Four Kitchens because we use it in the version of Emulsify, and we may be able to allocate some of our JavaScript engineers to help maintain it if that would be helpful. Thanks for your work on it.
I am experiencing the same issue with nested embeds and @JamesB797 hack does seem to fix it for us too, but I'm concerned if this the right fix and if it might cause other issues. Is there any update on when the real fix will be implemented?
Thanks for your hard work on this project.
Any update on this? I'm having the same problem and @JamesB797 hack also fixed it for me.
I would really appreciate a fix for this.
+1 for @JamesB797 fix
Can we submit this as a PR?