
Easy layout in forced places: helpers, decorators, form elements
Many already know that in views it is not recommended to use logic or generally any data manipulations. To do this, such code is placed in decorators , custom form elements , components, and simply helpers in the end.
Indeed, with this approach, view files begin to look better. But custom form elements and helpers are simply unbearable.
But there is a simple and elegant way to make them cleaner and simpler ...
For example, take a custom form element
This element is easy to call from the form:
but having simplified the form itself, the custom element has become difficult to understand. Its structure is easy to get confused.
The solution is to use Arbre - Ruby Object Oriented HTML Views.
It makes it easy to use layout in code, as well as create reusable components. Arbre was born in the acive_admin project and is, in fact, its foundation.
Let's start by adding an assistant to the base class of form elements. This is one of the rare examples of an appropriate monkey patch.
Now we can refactor the form element:
They removed all unnecessary, left only what is really needed. The code looks nicer and clearer.
And so to summarize a brief summary.
1. Use
2. saves us from having to use the garbage
3. And the most interesting thing is the components.
Another amazing fact is that
Immediately after the announcement, the component is ready for use anywhere in the arbre context. Now instead of:
can write
and at the output we get the code:
In general, arbre helps to make the inevitable - layout in the code, more enjoyable. Recommend.
Indeed, with this approach, view files begin to look better. But custom form elements and helpers are simply unbearable.
But there is a simple and elegant way to make them cleaner and simpler ...
For example, take a custom form element
PriceRangeInput
.class PriceRangeInput < SimpleForm::Inputs::Base
def input
output = template.content_tag(:div, class: 'j-price-slider') do
div = ''
div << template.content_tag(:div, class: 'row') do
row = ""
row << template.content_tag(:span, class: 'span3') do
@builder.input(:min_total_price, label: false, input_html: { class: 'input-small j-min-total-price'})
end
row << template.content_tag(:span, class: 'span3') do
@builder.input(:max_total_price, label: false, input_html: { class: 'input-small j-max-total-price'})
end
row.html_safe
end
div << template.content_tag(:div, class: 'row') do
template.content_tag(:span, class: 'span6') do
template.content_tag(:div, class: 'j-slider', :data => :slider_data) do
end
end
end
div.html_safe
end
output.html_safe
end
end
This element is easy to call from the form:
= simple_form_for current_search_form, :url => :search, :method => "get" do |f|
= f.input :price_range, :label => false, :as => :price_range
but having simplified the form itself, the custom element has become difficult to understand. Its structure is easy to get confused.
There is an exit
The solution is to use Arbre - Ruby Object Oriented HTML Views.
It makes it easy to use layout in code, as well as create reusable components. Arbre was born in the acive_admin project and is, in fact, its foundation.
Get to the point
Let's start by adding an assistant to the base class of form elements. This is one of the rare examples of an appropriate monkey patch.
class SimpleForm::Inputs::Base
private
def arbre assigns={}, &block
Arbre::Context.new assigns.reverse_merge(:builder=>@builder), template, &block
end
end
Now we can refactor the form element:
def input
arbre slider_data: slider_data do
div class: 'j-price-slider' do
div class: 'row' do
span class: 'span3' do
builder.input :min_total_price, label: false, input_html: { class: 'input-small j-min-total-price'}
end
span class: 'span3' do
builder.input :max_total_price, label: false, input_html: { class: 'input-small j-max-total-price'}
end
end
div class: 'row' do
span class: 'span6' do
div class: 'j-slider', data: slider_data
end
end
end
end
end
They removed all unnecessary, left only what is really needed. The code looks nicer and clearer.
Advantages of Arbre
And so to summarize a brief summary.
1. Use
Arbreallows you to get rid of the buffer for storing generated tags:
# было
buffer = ''
buffer << template.content_tag(:div, class: 'row') do
...
buffer << template.content_tag(:div, class: 'row') do
buffer.html_safe
# стало
div class: 'row' do
...
div class: 'row' do
...
2. saves us from having to use the garbage
content_tag
in the code and gives vozmzhonost directly specify your tag:# было
template.content_tag(:div, class: 'row')
# стало
div class: 'row'
3. And the most interesting thing is the components.
Proprietary components
Another amazing fact is that
Arbre
it makes it easy to add your own elements and use them in any context.class Row < Arbre::Component
builder_method :row
def build(title, attributes = {})
super(attributes.merge class: 'row')
end
end
Immediately after the announcement, the component is ready for use anywhere in the arbre context. Now instead of:
template.content_tag(:div, class: 'row') do
...
can write
row do
...
and at the output we get the code:
...
In general, arbre helps to make the inevitable - layout in the code, more enjoyable. Recommend.