I have the following accordion generator which works fine when included directly in the view:
<%
def collapser(name)
fad = {
class: 'collapsed',
data: {toggle: 'collapse', parent: '#accordion_id'},
href: "##{name}",
aria: {expanded: 'true', controls: name}
}
tag.div(class: 'panel panel-default') do
tag.div(class: 'panel-heading', role: 'tab') do
tag.p(class: 'panel-title') do
tag.a(fad) do
tag.span do
t("section.#{name}.title")
end
end
end
end +
tag.div(id: name, class: 'panel-collapse collapse', role: 'tabpanel', style: 'height: 0px;', aria: {labelledby: name}, data: {parent: '#accordion_id'}) do
tag.div(class: 'panel-body') do
tag.div(class: 'uncode_text_column') do
yield
end
end
end
end
end
%>
<%= tag.div(id: 'accordion_id', class: 'panel-group', role: 'tablist', aria: {multiselectable: 'true'}) do %>
<%= collapser('example') do %>
<%= tag.p t('section.example.nub.row1') %>
<% end %>
<% end %>
Now I wanted to move toward a more clean implementation by:
- moving
collapser
to the matching controller - make a
generic_collapser(name, parent)
so- it's more broadly accessible in other part of the code base
- this specific collapser can be implemented as a call to
generic_collapeser(name, 'accordion_id')
But I'm stuck with the first step, as I'm not able to handle the context change properly. First, tag
is no longer accessible, but simply assigning tag = view_context.tag
seems to do the job. However, I didn't found a way to transpose yield
statement. I tried the following
- keep
tag.div(class: 'uncode_text_column') { yield }
- use
tag.div(class: 'uncode_text_column') { view_contex{yield} }
- use
tag.div(class: 'uncode_text_column') { view_contex(&block) }
, together withdef collapser(name, &block)
But none gave the expected result.
Hints toward good resources to better understand view_context
, yield
and block management would also be welcome, especially tutorial with exercises.
What's this &block in Ruby? And how does it get passed in a method here?