-
Notifications
You must be signed in to change notification settings - Fork 19
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 Conditional Context Shorthand Statements Cause Unexpected Errors #159
Comments
Yeah – I can see why that would be counter-intuitive. The reason is that the above code is equivalent to
That is, the |
Actually, looking at https://github.com/zendesk/curly/blob/master/lib/curly/compiler.rb#L119-L135 I'm surprised to see this behavior, so I guess it's a block. Can you write a failing test for this? |
You would expect the context to change in that example because it's a "context tag" - it's entire behavior is to change the context you're currently running. However, a "conditional tag"'s behavior is to output based on a condition - not to change the context. It makes no sense for a conditional tag to have a side effect of changing the context. This branch contains a failing test for it. |
As a note, when |
I'll take a look at fixing this. It's a bit trickier than I had hoped for. |
I've been thinking about adding a {{@article}}
{{@author}}
{{name}} posted this on {{@..}}
{{posted_at}} <!-- `posted_at` refers to the article context here. -->
{{/..}}.
{{/author}}
{{/article}} I'm not happy about the syntax, but the semantics would allow us to fix this issue by injecting such a block between the conditional block node and its children. |
Maybe you can refer to the previous context by having a However, with the "macro" # normally, curly does this:
options_stack << options
presenters << presenter
buffers << buffer
buffer << presenter.user() do |item|
options = options.merge("user" => item)
buffer = ActiveSupport::SafeBuffer.new
presenter = ::UsersPresenter::ShowPresenter::UserPresenter.new(self, options)
buffer.concat(presenter.name() { |*args| yield(*args) }.to_s)
buffer
end
buffer = buffers.pop
presenter = presenters.pop
options = options_stack.pop
# However, since we're probably going to use that presenter again for similar
# things, it makes sense to cache it.
contexts[:user] ||= do
presenter.user() do |item|
options = options.merge("user" => item)
::UsersPresenter::ShowPresenter::UserPresenter.new(self, options)
end
end
buffer.concat(contexts[:user].name() { |*args| yield(*args) }.to_s) This should probably speed things up and use less memory. |
I've previously thought about caching presenter instances, however this seems to be orthogonal to the issue at hand... Probably the right thing to do here is to rewrite parts of the compiler to generate different code paths for blocks that change context vs. blocks that don't. I'm not sure when I'll have time for this work, though :-/ |
What a mouthful. This is what it boils down to:
Is an error. Instead, curly expects this:
That is, while inside of the conditional block, the contextual block was entered - meaning all components are resolved against the
user
contextual block, which is not the desired behavior.The text was updated successfully, but these errors were encountered: