Ultimamente temos trabalhado em alguns projetos que necessitaram de vários CRUDs na administração como páginas mostrando listas de atributos. E com passar do tempo, estávamos ficando entediados de tanto copiar e colar código como este para cada atributo em nossas páginas:

<p>
  <strong class="label">Name</strong><br />
  <%= @person.name %>
</p>

Nós já tinhamos criado um helper para fazer o trabalho para nós, mas copiar este helper de um projeto para outro não é DRY. Então decidimos criar uma nova gem, chamada ShowFor.

ShowFor é uma DSL para auxiliá-lo a mostrar uma lista de atributos, usando I18n, perfeito para páginas de visualização em interfaces CRUDs. Ele permite que você substitua duplicação de código/html em suas views usando uma sintaxe mais atraente. Vejamos o que podemos fazer!

Atributos

Vamos imaginar que temos um model Person, que possui os atributos first_name, last_name, age, photo, e confirmed. As linhas abaixo criam uma lista de valores para um registro específico:

<% show_for @person do |p| %>
  <%= p.attribute :first_name %>
  <%= p.attribute :last_name %>
  <%= p.attribute :confirmed? %>
  <%= p.attribute :created_at, :format => :short %>
  <%= p.attribute :age, :if_blank => "No age" %>
 
  <% p.attribute :photo do %>
    <%= image_tag(@person.photo_url) %>
  <% end %>
<% end %>

E este é o código HTML que você tem como resultado:

<div class="show_for person" id="person_1">
  <p class="wrapper person_first_name"><strong class="label">First name</strong><br />Carlos</p>
  <p class="wrapper person_last_name"><strong class="label">Last name</strong><br />Antonio</p>
  <p class="wrapper person_confirmed"><strong class="label">Confirmed?</strong><br />Yes</p>
  <p class="wrapper person_created_at"><strong class="label">Created at</strong><br />08 Mar 11:30</p>
  <p class="wrapper person_age"><strong class="label">Age</strong><br />24</p>
  <p class="wrapper person_photo"><strong class="label">Photo</strong><br />
    <img alt="Rails" src="/images/rails.png?1268047643" />
  </p>
</div>

Como se pode ver, você terá uma marcação HTML padrão, com classes e ids para ajudá-lo no design com CSS. E caso tenha notado, estamos usando opções extras em alguns atributos, vamos dar uma olhada em algumas delas:

  • :format permite que você defina um formato a ser usando com I18n, somente para atributos date/time, como você usaria com o helper l.
  • :if_blank define o que será mostrado caso o atributo esteja em branco. Pode ter um valor padrão via I18n.
  • do...end: usando blocos você mesmo pode manusear o conteúdo para o atributo específico, como fizemos no exemplo para o atributo photo.

Atributos booleanos, como nosso :confirmed, também possuem um valor padrão para true e false, e podem ser configurados através de I18n. Se você deseja mostrar “Sim” e “Não” no lugar de “Yes” e “No” respectivamente, só precisa mudar seu arquivo I18n. Você também pode passar a opção :escape para não escapar o conteúdo (true por padrão).

Associações

ShowFor também funciona com associações. Por exemplo, podemos adicionar que nosso Person agora pertence a um model City com um atributo nome, e que também possui e pertence a muitas Tags. Para gerenciar o primeiro, podemos fazer:

<%= p.association :city %>

ShowFor irá adivinhar o atributo correto para mostrar procurando todas as possibilidades configuradas em ShowFor.association_methods e neste caso escolhendo :name. Mas é claro, você pode modificar isso se precisar:

<%= p.association :city, :using => :full_name %>
<%= p.attribute :full_name, :in => :city %>

Ambas as possibilidades acima terão a mesma saída, apenas escolha a que você mais gostar.

Manusear coleções é tão fácil quanto associações belongs_to. Você simplesmente passa a associação para ShowFor e ele irá saber se é uma coleção ou não, gerando uma lista de elementos usando tags ul e li.

<%= p.association :tags %>

Entretando, se você quiser renderizar a coleção inline, pode usar as opções :to_sentence e :join:

<%= p.association :tags, :to_sentence => true %>
<%= p.association :tags, :join => ',' %>

Também é possível passar um bloco para a coleção. O ShowFor criará a tag wrapper (ul por padrão nesse caso) e retornará cada elemento da coleção para você gerenciá-lo:

<% a.association :tags do |tag| %>
  <li><%= link_to tag.name, tag %></li>
<% end %>

Labels

Você deve ter percebido que o ShowFor possui um label padrão usando a tag strong. Ele também expõe a você o método label como um helper, para que possa usá-lo quando desejar:

  <%= p.label :first_name %>
  <%= p.label :age, :id => 'person_age' %>
 
  <strong class="label">First name</strong>
  <strong class="label" id="person_age">Age</strong>

Instalação

O ShowFor, em sua versão 0.2.0, já é compatível com o Rails 3. Você pode seguir as instruções no README para instalá-lo.

Se você está usando o Rails 2.3.x, pode dar uma olhada no branch 0.1, e seguir as instruções no README deste branch para utilizá-lo.

E após a instalação, não se esqueça de executar o generator e dar uma olhada no initializer gerado, que permite que você configure várias partes do ShowFor.

script/generate show_for_install

Fechando

ShowFor ajuda você a mostrar os atributos de seus objetos facilmente com uma marcação html padrão, e pode ser totalmente configurado para atender sua necessidade. Ele tem nos ajudado em todos os projetos, e esperamos que ele possa ajudá-lo também. Se você tiver alguma dúvida, por favor dê uma olhada no README, existem muitos exemplos e documentação lá.

E você? Possui algum helper que usa todos os dias e que poderia ser transformado em um plugin/gem? Não hesite em fazer isto, ficaremos contentes em ver seu trabalho!

Divirta-se!

Comments are closed.