Ruby On Rails integration / Defining component views

Let's go over a simple example in HTML and then rewrite it using webface_rails helpers.

That's a pretty long piece of code and even if we rewrite it in haml, it would still look long:

.offerList{ data: {                                          |
    attr_map: "visible:data-visible,per_page:data-per-page", |
    component_class: "OfferListComponent",                   |
    per_page": 10,                                           |
    visible: true                                            |
  }}                                                         |

  .offer{ data: {
      attr_map: "visible:data-visible,disabled:disabled", |
      component_class: "OfferComponent",                  |
      visible: true,                                      |
    }, disabled: false }                                  |

    %div{ data: { component_part: "body" }}
      %span{ data: { component_attr: "title"       } Selling a BMW, year 2010
      %span{ data: { component_attr: "description" } Very good condition

The | character at the end of some of the lines means that all following lines that end with | will be evaluated as though they were on the same line. Note that even the last line in the multiline block should end with |. Read more in HAML documentation

webface_rails helpers allow you to do this:

= define_component :offer_list, ".offerList",       |
  mapped_attrs: { per_page": 10, visible: true } do |

  = define_component :offer, ".offer", |
    attr_map: "disabled:disabled",     |
    disabled: false,                   |
    style: "font-weight: bold",        |
    mapped_attrs: { visible: true } do |

    = component_part :body do
      = component_attr :title, "span", text_content: "Selling a BMW, year 2010"
      = component_attr :description, "span", text_content: "Very good condition"

It might seem like we haven't won a lot by using the helpers, but, firstly, it becomes very apparent how many duplicate words we need to write if our component has a lot attributes (mapped_attrs saves us this work). But then, also, once we employ the #component helper and move our #define_component calls into separate views in the app/views/webface_components directory, it becomes exceptionally easy to reuse components with just one line of code.

Another thing to notice is that the options argument (the hash, which is the last argument) passed to #define_component has a much more flat strcuture. For example, in the haml code, we have to be careful to specify the value for disabled attribute outside of the data hash, however we don't have to think about that when using webface_rails as it would correctly imply html-attribute name from the attr_map provided. Because we specified attr_map: "disabled:disabled" the helper now knows to put the value in the disabled= html attribute, and NOT into data-disabled=.