-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Allow #
to be used as an inline comment tag
#1401
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{% assign discouraged = true # This comment is parsed as part of the assign tag %}
I can definitely picture people learning about comment syntax by example and then assuming this would work. We need some kind of strategy there.
Perhaps we should assess whether From an implementation perspective, we wouldn't be able to just ignore everything after the first |
Same feedback: def test_conditional
assert_template_result('true', '{% if true # comment %}true{% else %}false{% endif %}')
# InlineCommentTest#test_conditional:
# Liquid::SyntaxError: Liquid syntax error (line 1): Unexpected character # in "true # comment"
end
def test_assign
assert_template_result('true', '{% assign test = true # comment %}{{test}}')
# InlineCommentTest#test_assign:
# Liquid::SyntaxError: Liquid syntax error (line 1): Unexpected character # in "{{true # comment }}"
end Not being familiar with the parsing process, is the only option to implement comments as a tag? Would we want to have a way to strip these completely when generating an intermediary representation so they are not part of the final execution path? I would rather not have tags even be aware there was comments in the first place. |
Comments are already implemented as tags, doing the same for inline comments makes the changes simpler and less likely to introduce a breaking change. Basically, I'm avoiding introducing a special case where there isn't a 1-1 correspondence between the tag syntax and a tag node. Breaking that would make the implementation more awkward, thus supporting inline comments at the end of other tags wouldn't introduce an InlineComment tag node for the same reason.
We can remove these when compiling to liquid-c VM code as will be done for the Comment tag in Shopify/liquid-c#96
This is just an implementation detail that should be opaque to all the other tags, since tag classes shouldn't be coupled to each other |
If |
Do you think we should ship this as is then iterate by trying to follow-up with support for comments at the end of tags? Or should I hold off on that exploration? |
If we consider it a tag, then maybe it's even better(easier to form a mental model) that you cannot add it at the end of another tag.
Reviewing back, should this not be made possible then? |
Spaces around tags aren't strictly required in any case, e.g. I don't really have much of an opinion on comments at the end of tags, as long as it crashes gracefully. |
My feedback was not for space before, but after a tag.
|
I guess it makes sense to have that be invalid until we add support for comments at the end of tags. |
5b3ec2e
to
d889127
Compare
I've updated the code to require a space after |
@@ -22,6 +22,6 @@ group :test do | |||
gem 'rubocop-performance', require: false | |||
|
|||
platform :mri, :truffleruby do | |||
gem 'liquid-c', github: 'Shopify/liquid-c', ref: 'master' | |||
gem 'liquid-c', github: 'Shopify/liquid-c', ref: 'inline-comment' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's is the plan here? Will you merge it remove current change so it point to master?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The liquid-c change can be safely merged first, then I'll update this to point back to master before merging.
That is because the underscores are part of the tag name and there is no tag called class Foo < Liquid::Tag
def initialize(tag_name, arg, tokens)
@arg = arg
end
def render(_)
@arg.to_s
end
end
Liquid::Template.register_tag('foo', Foo)
puts Liquid::Template.parse("{%foo#bar%}").render # => "#bar"
puts Liquid::Template.parse("{%foo!bar%}").render # => "!bar" I think most people would expect the comment syntax to work without the space. |
d889127
to
5e8e5e8
Compare
Oh right, spaces after the tag name are just needed to separate it from other word characters, since it just requires a non-word character to end the tag.
I've removed that last commit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we are good now! I'd love to see @pushrax case in the tests as if anything is to break in future iterations I think it is going to be that (since tag registration are global, I'm not sure it can be done without some tinkering).
end | ||
|
||
def test_comment_inline_tag | ||
assert_template_result('ok', '{% echo "ok" # output something from a tag %}') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth noting that this removes a lot of the benefit of treating #
as its own tag, because it means the concern leaks into the syntax of other tags too.
This also has implications for the API, since we'd have to either
- Do pre-processing on all tag input before passing it, which is a breaking change in a strict sense
- Only support it for our own tags, which could lead to inconsistencies for other clients.
The second of these may still be the right call, but special-casing those tags could be more complex in Liquid-C.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What exactly is the benefit of treating it as a tag? My (limited!) experience with parser creation suggests that comments are usually dropped very early in the process of parsing/lexing and this feels like the right approach for liquid as well.
11ce2a6
to
0fc45ca
Compare
I've been thinking about how to extend inline comments to all tags, and it occurred to me—if the plan is to implement
Interestingly, all 4 of these examples already render without issue in Shopify's theme editor due to it's lax error handling. They only raise a "potential issue" warning inside of a development shop: |
Not all tags support filters, so adding a
Yeah, the lax parsing makes it hard to extend the syntax in a backwards compatible way, since avoiding breaking working liquid code (without usage testing) requires finding something that is currently considered an error. Essentially, syntax errors reserve syntax for future features. Instead, the lax parser just scans over a regular expression that it doesn't match on to find the filter, including the |
Not sure this is helpful in the overall picture, but currently doesn't the parser just skip everything until the next pipe character? It appears to me that the parser is failing to match the first word (
|
It does that for the first pipe character. After that, it treats anything that doesn't match Liquid::Variable::FilterParser.
What would help would be if less invalid code was saved in Shopify, so it doesn't make it look like code that depends on these quirks. This invalid liquid can be tested using this gem directly (e.g. |
def test_test_syntax_error | ||
assert_template_result('fail', '{% #This doesnt work %}') | ||
|
||
assert false | ||
rescue | ||
# ok good | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly, this test is saying that a space is required after #
.
def test_tag_ws_stripping | ||
assert_template_result('', ' {%#- This text gets ignored -#%} ') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the reason you are proposing supporting this style. Does it have any semantic difference?
Other than this test case, it seems like #
is supposed to treat the rest of the line as a comment, but here it seems to be integrated into the start tag. So does this have different semantic for multi-line comments like the following?
{%#- This is clearly a comment
echo "but how about this line?" -#%}
I'm also unsure if you are proposing that the -#%}
end tag should have any significance over -%}
.
Worth noting that NunJucks (a popular templating language in SSG that is a near relative to liquid) uses the [sidebar: webstorm integration is really convenient here. comment and uncomment are really easy] |
@timdmackey but does it actually render anything when you load the page? Sometimes, Liquid errors appear dumped in the rendered page even if the theme code editor has no complaints. PS: Actually this works because you can pass any random set of characters as a filter, and the engine will just ignore that unrecognized filter and move on to the next. It has nothing to do with Interestingly, this may allow us to add comments anywhere already by using unrecognized filter as a hack: Update: It works as I thought it would. But you can't use |
Closing in favour of #1498 |
1 similar comment
Closing in favour of #1498 |
Fixes #1393
Depends on Shopify/liquid-c#144
@Shopify/guardians-of-the-liquid
Allow
#
to be used as an inline comment tag, ignoring everything after it in the tag.For example, instead of
{% comment %}Single line comment{% endcomment %}
you can use
{% # Single line comment %}
Spaces around
#
aren't necessary, so this also works{%#This also works %}
Using this after another tag (e.g.
{% assign discouraged = true # This comment is parsed as part of the assign tag %}
) would cause it to be parsed as part of that tag, so is not recommended since we can't ensure consistency between tags and backwards compatibility (especially considering that there are application defined tags). Instead, use a separate tagWhitespace control characters work the same way as other tags.
This inline comment also works in liquid tags, so instead of
you can use