fix liquid template argument parsing and shortcode undefined values #2367
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This fixes a major bug with liquid shortcodes not working in layout templates. They end up randomly getting
undefined
values for arguments after the first argument due to an order of execution issue with a changingscope
context being sent to evalValue.I changed it from running the promise using await immediately to calling the promise immediately instead so it gets the correct current scope value. I then use
await Promise.all(pendingPromises)
to wait for each promise to resolve.There is a separate example here which shows the differences in order of execution with calling the promise immediately with await(broken) vs calling it without await and then later awaiting all of the promises(fixed).
Demo/why it fixes and didn't work before
Notice how the regular version starts the two functions concurrently and their counter is then randomly iterated between the the functions. Consider each function an eleventy input file and the counter to be the scope in the liquid parser. You end up with the undefined arguments bug in this setup because the scope changes out of order compared to where the variables are being processed.
Compare with the fixed version under it in which the first file is completely executed then the next one. Nodejs is single threaded anyways so executing it in order synchronously while still using async/await is fine. We are just fixing the processing order here so that the counter/scope are processed in the corresponding order to their arguments.
Example.js