liquid
liquid copied to clipboard
Comparison operators are whitespace-sensitive
I was messing around in Jekyll with Liquid and discovered this weird behaviour when I hit auto-format on an HTML file:
{% assign foo = "bar" %}
{% if foo == "bar" %}
true
{% else %}
false
{% endif %}
gives the result true
, whereas
{% assign foo = "bar" %}
{% if foo=="bar" %}
true
{% else %}
false
{% endif %}
gives the result false
.
Furthermore,
{% assign foo = "" %}
{% if foo=="bar" %}
true
{% else %}
false
{% endif %}
gives the result true
, as though Liquid is evaluating against the empty string.
Can anyone replicate this? Is this documented (and I missed it)? I can't seem to find any notes on how whitespace is relevant to Liquid, and I would expect it to obey the same whitespace rules as HTML (ie. ignore all unnecessary whitespace). #428 relevant?
The problem is that foo=="bar"
gets parsed as a single Liquid::QuotedFragment in Liquid::If::Syntax as if it were 'foo=="bar"'
due to liquid's lax expression parsing. It will behave as expected with the strict error mode but not the lax error mode.
I can replicate this, but I don't think we were previously aware of this liquid quirk.
@Shadowen: This should be fixed in Jekyll 3, where the strict parser is the default behaviour.
Wow, this is one of my favourite quirks yet. I thought previously that the lax parser was at least whitespace-invariant.
I vote to mark this #wontfix in the lax parser since I bet there are templates that will break if we do :crying_cat_face:.
This should probably also work in warn mode, since it parses strictly then falls back to lax mode only if it can't be strictly parsed. So I guess warn mode might be the most lax mode.
We should run a template comparator job with the strict vs lax parser to test if this actually affects any production templates. It's quite possible it doesn't affect many, and if it does fixing this might not break them.
Still not fixed. This is not a quirk. It is a timewasting bug. This is year 2022. I'll check back in another 5 years.
Yes, it is a bug, but we need to consider any existing liquid code that could break from fixing it.
The strict parser ended up acting like another version of liquid, which allowed it to essentially fix this, so adopting the strict parser can be a way of avoiding this problem where it is possible. This issue was raised in the context of Jekyll, which now defaults to warn mode, which I believe avoids this issue.
In the context of Shopify, I believe Shopify parses sections using the strict parser. So, if I understand correctly, you would be able to adopt those in order to avoid this issue in Shopify.