Легкая верстка в вынужденных местах: хелперы, декораторах, элеманты форм

от автора

Многие уже знают о том что во вьюхах не рекомендуется использовать логику и вообще какие-либо манипуляции с данными. Для этого подобный код выносят в декораторы, кастомные элементы формы, компоненты и просто хелперы в конце-концов.

Действительно, при таком подходе view-файлы начинают выглядить лучше. Но кастомные элементы форм и хелперы становятся просто невыносимыми.

Но есть простой и элегантный способ как сделать их чище и проще…

К примеру возьмем кастомный элемент формы 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 

Этот элемент легко вызвать из формы:

= simple_form_for current_search_form, :url => :search, :method => "get" do |f|     = f.input :price_range, :label => false, :as => :price_range 

но упростив саму форму, кастомны элемент стало сложно понимать. В его структуре легко запутаться.

Выход есть

Решение — использовать Arbre — Ruby Object Oriented HTML Views.

Он позволяет легко использовать верстку в коде, а также создавать повторно используемые компоненты. Arbre рожден в проекте acive_admin и является, по сути, его основой.

Ближе к делу

Начнем с добавление помощничка в базовый класс элементов форм. Это один из редких примеров уместного monkey patch.

class SimpleForm::Inputs::Base private   def arbre assigns={}, &block     Arbre::Context.new assigns.reverse_merge(:builder=>@builder), template, &block   end end 

Теперь можем зарефаторить элемент формы:

 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 

Убрали все лишнее, оставили только то, что действительно нужно. Код выглядит приятнее и понятнее.

Достоинства Arbre

И так подведем краткое резюме.

1. Использование

Arbre

позволяет избавиться от буфера, для хранение генерируемых тегов:

# было  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. Избавляет нас от необходимости применять мусорный content_tag в коде и дает возмжоность прямо указывать необходимый тег:

# было template.content_tag(:div, class: 'row')   # стало div class: 'row' 

3. И самое интересное — компоненты.

Собственные компоненты

Удивительное еще и то, что Arbre позволяет легко добавлять собственные элементы и использовать их в любом контексте.

class Row < Arbre::Component   builder_method :row    def build(title, attributes = {})     super(attributes.merge class: 'row')   end end 

Сразу после обьявления компонент готов к использованию в любом месте arbre-контекста. Теперь вместо:

template.content_tag(:div, class: 'row') do   ... 

можно писать

row do   ... 

а на выходе полчим код:

 <div class="row">    ... 

В общем arbre помогает сделать неизбежное — верстку в коде, более приятным. Рекомендую.

ссылка на оригинал статьи http://habrahabr.ru/post/184528/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *