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
Broken Capturing (I guess) #10
Comments
|
OK, thank you. Note about arguments: it works with parentheses: <%|= foo block: (proc do %>
<p>Hello!</p>
<%| end) %> |
Oh, problems in cycles :( <%
def foo
[{ name: 'Alex' }, { name: 'Ivan' }, { name: 'Boris' }]
.reduce('') do |_mem, obj|
p yield(obj)
end
end
%>
<%|= foo do |obj| %>
<h1>Hello, <%= obj[:name] %></h1>
<%| end %> Output: pry: main > eval(Erubi::CaptureEndEngine.new(File.read('.test.erb')).src)
"\n <h1>Hello, Alex</h1>\n"
"\n <h1>Hello, Alex</h1>\n\n <h1>Hello, Ivan</h1>\n"
"\n <h1>Hello, Alex</h1>\n\n <h1>Hello, Ivan</h1>\n\n <h1>Hello, Boris</h1>\n"
=> "\n\n <h1>Hello, Alex</h1>\n\n <h1>Hello, Ivan</h1>\n\n <h1>Hello, Boris</h1>\n\n" Why does the concatenation occur with the previous result? |
Probably because it was never tested with a loop. I think it's safe to say that is not the expected behavior. I'll look into this today and see if I can fix it. |
Thanks, I'll wait for updates! |
I misread the previous code. I thought the the "Hello, Alex" result was injected into the template 3 times, and the "Hello, Ivan" was injected into the template 2 times. Now I can see each is only injected a single time, which is what I would expect. The reason that
Then In general when you are using the capture_end support, any methods you want to be callable from the template using In your case, if you are just trying to output that heading for each name, you probably don't want to use the capture support, you should probably just use regular
I did notice a fairly large issue with the capture_end support, which is that the escaping flag is inverted. That will definitely need to be fixed, I'll work on that soon. |
No, there is no output with this tag :( And
Real case: # common_list.erb
<ul>
<% items.each do |item| %>
<li>
<header>
<%= yield(item) %>
</header>
<!-- content -->
</li>
<% end %>
</ul> # articles_list.erb
<!-- there is I tried to use capture end or block-as-variable (works the same in cycles) -->
<%= render 'common_list' do |article| %>
<h1><%= article.title %><h1>
<% end %> # pages_list.erb
<%= render 'common_list' do |article| %>
<h1>
<%= page.title %>
<small><%= page.author %></small>
<h1>
<% end %>
Yes, I noticed this. I apologize for not writing about this. Another strange thing: |
There should be output with template = <<END
<% foo do |obj| %>
<h1>Hello, <%= obj[:name] %></h1>
<% end %>
END
def foo
[{ name: 'Alex' }, { name: 'Ivan' }, { name: 'Boris' }]
.reduce('') do |_mem, obj|
yield(obj)
end
end
eval Erubi::CaptureEndEngine.new(template).src
=> " <h1>Hello, Alex</h1>\n <h1>Hello, Ivan</h1>\n <h1>Hello, Boris</h1>\n"
The reason behind the I'm not sure exactly what you want as there is no definition for the @common_list = <<END
<ul>
<% @items.each do |item| %>
<li>
<header>
<%= yield(item) %>
</header>
<!-- content -->
</li>
<% end %>
</ul>
END
@articles_list = <<END
<%|= render 'common_list' do |article| %>
<h1><%= article[:name] %><h1>
<%| end %>
END
@items = [{ name: 'Alex' }, { name: 'Ivan' }, { name: 'Boris' }]
def render(template)
render_partial(template) do |item|
@a = String.new
yield item
end
end
def render_partial(template)
eval Erubi::CaptureEndEngine.new(instance_variable_get("@#{template}")).src
end
eval Erubi::CaptureEndEngine.new(@articles_list, bufvar: '@a').src which outputs:
Part of the reason you don't have to manually do this in Rails is that |
Thanks for the detailed explanation!
Work with
There is working code in my case (with require 'erubi'
require 'erubi/capture_end'
@common_list = <<END
<ul>
<% @items.each do |item| %>
<li>
<header>
<%= yield(item) %>
</header>
<!-- content -->
</li>
<% end %>
</ul>
END
@articles_list = <<END
<%|== render 'common_list' do |article| %>
<% @header = '' %>
<h1><%= article[:name] %><h1>
<%| end %>
END
@items = [{ name: 'Alex' }, { name: 'Ivan' }, { name: 'Boris' }]
def render(template)
render_partial(template) do |item|
yield item
end
end
def render_partial(template)
eval Erubi::CaptureEndEngine.new(instance_variable_get("@#{template}")).src
end
puts eval Erubi::CaptureEndEngine.new(@articles_list, bufvar: '@header').src The same example with block in variable: require 'erubi'
require 'erubi/capture_end'
@common_list = <<END
<ul>
<% @items.each do |item| %>
<li>
<header>
<%= header.call(item) %>
</header>
<!-- content -->
</li>
<% end %>
</ul>
END
@articles_list = <<END
<%|== render 'common_list', header: (proc do |article| %>
<% @header = '' %>
<h1><%= article[:name] %><h1>
<%| end) %>
END
@items = [{ name: 'Alex' }, { name: 'Ivan' }, { name: 'Boris' }]
def render(template, header: nil)
render_partial(template, header: header) do |item|
yield item
end
end
def render_partial(template, header: nil)
eval Erubi::CaptureEndEngine.new(instance_variable_get("@#{template}")).src
end
puts eval Erubi::CaptureEndEngine.new(@articles_list, bufvar: '@header').src Thanks again. |
But what if I need to use two or more blocks inside template? require 'erubi'
require 'erubi/capture_end'
@common_list = <<END
<ul>
<% @items.each do |item| %>
<li>
<header>
<%= header.call(item) %>
</header>
<section>
<%= section.call(item) %>
</section>
<!-- content -->
</li>
<% end %>
</ul>
END
@articles_list = <<END
<%|=
render 'common_list',
header: (proc do |article| %>
<% @header = '' %>
<h1><%= article[:name] %><h1>
<% end),
section: (proc do |article| %>
<% @section = '' %>
<%= article[:age] %>
<%| end) %>
END
@items = [
{ name: 'Alex', age: 24 },
{ name: 'Ivan', age: 22 },
{ name: 'Boris', age: 26 }
]
def render(template, header: nil, section: nil)
render_partial(template, header: header, section: section) do |item|
yield item
end
end
def render_partial(template, header: nil, section: nil)
eval Erubi::CaptureEndEngine.new(instance_variable_get("@#{template}")).src
end
puts eval Erubi::CaptureEndEngine.new(@articles_list, bufvar: '@header').src
|
The capture_end support uses a stack of |
Sorry, my bad. It works without complications. But there is probably another strange bug, with condition inside captured block. I'll try to reproduce it in minimal example. |
Let's take your example from here: #10 (comment) And just add: <% if article[:name] == 'Alex' %>
That's Alex!
<% end %> The result code: require 'erubi'
require 'erubi/capture_end'
@common_list = <<END
<ul>
<% @items.each do |item| %>
<li>
<header>
<%= yield(item) %>
</header>
<!-- content -->
</li>
<% end %>
</ul>
END
@articles_list = <<END
<%|= render 'common_list' do |article| %>
<h1><%= article[:name] %><h1>
<% if article[:name] == 'Alex' %>
That's Alex!
<% end %>
<%| end %>
END
@items = [{ name: 'Alex' }, { name: 'Ivan' }, { name: 'Boris' }]
def render(template)
render_partial(template) do |item|
@a = String.new
yield item
end
end
def render_partial(template)
eval Erubi::CaptureEndEngine.new(instance_variable_get("@#{template}")).src
end
puts eval Erubi::CaptureEndEngine.new(@articles_list, bufvar: '@a').src The output: <ul>
<li>
<header>
<h1>Alex<h1>
That's Alex!
</header>
<!-- content -->
</li>
<li>
<header>
</header>
<!-- content -->
</li>
<li>
<header>
</header>
<!-- content -->
</li>
</ul> There are no names when condition is falsey… You can turn condition into And all the content before falsey condition will disappear. |
For now I can't reproduce it in Erubi tests. 😔 |
Work-around and related reason by @WorstOfAny: it's because of |
@AlexWayfer Maybe you want the |
Yes, it helps. Thank you. Probably it should be |
I'm definitely considering true by default for Erubi 2. |
Oh, thank you. Is there any plans for Erubi 2? |
No current planned release date. Few people are using capture_end, and bumping the major just for changes to capture_end is not something I plan to do. If I have to bump the major for something else, then I'll probably include changing the default in capture_end. |
So, it can take years before major update… it's sadly. Thanks. |
(From
README
)It works. But these code blocks don't work:
So,
<%|
tag exists inREADME
, but I can't use it.Thanks.
The text was updated successfully, but these errors were encountered: