terça-feira, 1 de janeiro de 2013

Que tal migrar para Haml?

Que tal começar 2013 migrando as telas de seus projetos Rails para Haml? Ou pelo menos de um de seus projetos?
A experiência pode ser mais empolgante do que você pensa!

O Rails utiliza ERb na camada de visão por padrão, mas é possível mudar para outras opções e até mesmo criar a sua própria.


Calma lá! Criar só é necessário (e inteligente) quando você pode oferecer uma inovação real, uma nova abordagem que não é possível em alguma solução já existente. Não sendo assim, temos o que é chamado de "Reinventar a roda", o que é um desperdício de tempo/dinheiro. Então, antes de criar algo, procure conhecer bem as opções já existentes.

E em Rails há duas principais linguagens de camada de visão. ERb (Embedded Ruby) segue o mesmo padrão oferecido por outras linguagens (JSP do Java, ASP, PHP, etc.), em que o conteúdo específico da linguagem em questão é inserido em meio a um documento HTML comum através de tags especiais.

Haml tem a mesma finalidade, porém abstrai também o HTML, tornando o trabalho do desenvolvedor mais objetivo e menos suscetível a erros, eliminando por exemplo a preocupação de fechar tags através da interpretação por indentação.

A interpretação por indentação é uma herança de linguagens mais pioneiras como Python, Haskell e o velho Cobol. Essa abordagem tem conquistado novos espaços, especialmente quando se trata de simplificar linguagens já existentes e "forçar" uma melhor organização do código. Um outro excelente exemplo que tem conquistado muito espaço e é destaque no GitHub é a linguagem CoffeeScript, que simplifica o desenvolvimento de JavaScript.

Primeiro passo



Haml pode ser utilizada como uma ferramenta de linha de comando, um módulo independente para qualquer aplicação Ruby, ou um plugin para uma aplicação em Rails. Vamos ver aqui o terceiro cenário.
Para adicionar Haml a seu projeto Rails é necessário adicionar a gem 'haml' a seu gemfile.
Após esse primeiro passo, basta mudar de .html.erb para .html.haml a extensão dos arquivos de visão que você desejar migrar para Haml. O trabalho restante será mudar o conteúdo desses arquivos.

Exemplos



O site oficial já de início apresenta um exemplo bem simples:
<section class=”container”>
  <h1><%= post.title %></h1>
  <h2><%= post.subtitle %></h2>
  <div class=”content”>
    <%= post.content %>
  </div>
</section>

%section.container
  %h1= post.title
  %h2= post.subtitle
  .content
    = post.content

Através deste exemplo já é possível identificar alguns detalhes de como Haml funciona.
  • Linha 1 - Uma tag sempre começa com percentual (%) e não necessita ser fechada
  • Linha 1 - A definição de uma classe CSS começa com um ponto (.) e pode ser diretamente associada às tags
  • Linha 2 - Uma expressão Ruby começa com um sinal de igualdade (=) e também pode ser diretamente associada às tags, ou isoladamente (linha 5)
  • Linha 4 - Tags div, por serem tão comuns, quando levam alguma classe podem ser omitidas
  • E o mais importante de tudo: A indentação delimita tudo.

E, ampliando a lista além do que o exemplo anterior nos oferece, temos mais alguns detalhes:
  • Da mesma forma que o ponto prefixa o nome de uma classe CSS, também o sustenido (#) define um id para a tag:
    %section#section1.container.small-container
    

    E o resultado em HTML:
    <section id="section1" class="container small-container">
    </section>
    
  • Mais de uma classe pode ser definida com este mesmo padrão, conforme exemplo anterior.

Atributos


Quando os atributos a serem definidos para determinada tag vão além de classes CSS e um id, é necessário utilizar um Hash de Ruby, conforme o exemplo abaixo de definição de um link:

%a{ "data-toggle" => "modal", href: "#role-options-#{user.id}", class: "btn btn-mini", type: "button"}
  = t "devise.user.change_ability"

E o resultado em HTML:
<a data-toggle="modal" href="#role-options-1" class="btn btn-mini" type="button">
  Change Ability
</a>

Expressões Ruby


No exemplo anterior já foi possível também exemplificar como as expressões #{} podem ser incluídas para construir um valor. Observe o valor do atributo href.
Quando uma linha em Haml não possui nenhum prefixo especial, ela é considerada como um texto simples que não sofrerá nenhuma interpretação, exceto se possuir expressões Ruby.
Observe que as duas representações abaixo são perfeitamente compatíveis:
%div
  = @user.name

%div
  #{@user.name}

A segunda abordagem é especialmente útil quando você desejar unir textos simples com expressões Ruby:
%div
  Bem-vindo #{@user.name}!

Controles de Fluxo


Conforme demonstrado anteriormente, o sinal de igualdade deve preceder um comando Ruby que produzirá um conteúdo para o HTML. Porém há situações em que o comando Ruby não produzirá nada para o HTML, tendo somente a função de iterar sobre alguma coleção ou tornar condicional algum trecho, através de loops e ifs, por exemplo. Nestes casos, um hífen (-) é utilizado.
- @users.each do |user|
  %tr
    %td= link_to user.name, user

- if user_signed_in?
  %li= link_to('Logout', destroy_user_session_path, :method=>'delete')
- else
  %li= link_to('Sign in', new_user_session_path)

Doctype


Para definir o Doctype de um documento, também já há comandos definidos. Abaixo listo três exemplos mais comuns, mas há muitos outros que podem ser conferidos na referência oficial.

!!!
Para
XHTML 1.0 Transitional
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


!!! 5
Para
XHTML 5
%gt;!DOCTYPE html%lt;


!!! 1.1
Para
XHTML 1.1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">



Os detalhes apresentados até aqui devem ser suficientes para você conseguir já migrar toda a camada de visão de algum dos seus projetos para Haml, mas se não forem, há alguns links ao final deste post que resolverão seu problema.


Por que utilizar Haml em vez de ERb?


Achei interessante incluir esta parte no post porque já vi muitas opiniões diferentes. A defesa religiosa de alguma abordagem ou tecnologia é sem sentido, visto que projetos diferentes apresentam necessidades diferentes e a solução mais adequada sempre será a que atende melhor o projeto no seu contexto específico.
A melhor resposta que vi para esta pergunta é: Dê uma estudada rápida em Haml e migre algumas de suas páginas. O encanto virá naturalmente!
Concordo plenamente com esta resposta e proponho que você realmente pegue uma de suas páginas, daquelas bem extensas, e converta para Haml. Com certeza no final você estará rindo sozinho.

Há pontos incontestáveis que você já deve ter percebido ao ler o post, como:
  • A redução de código
  • A organização pela indentação
  • A menor propensão a erro por não existir mais o fechamento de tags.


Há, porém, pontos contestáveis! Quero então enumerar em seguida alguns pontos colocados por desenvolvedores da comunidade que achei realmente pertinentes e acrescentar minha conclusão sobre cada um.

  • Haml deixa o código feio!
    De fato, a primeira impressão pode não ser tão boa, porém após fazer aquela experiência com algumas (ou várias) de suas telas, você perceberá que existe uma beleza (e limpeza) muito maior no código final em Haml do que no anterior em ERb. Na minha opinião, HTML é feio, o conceito XML de abrir e fechar tags é maçante e muito propenso a erro, tanto que uma prática comum é colocar comentários no fechamento de tags que iniciaram muitas linhas antes.

  • A preocupação com tags vira preocupação com espaços
    Isso é verdade. Se a identação for com 2 espaços em uma parte e 3 em outra, você será xingado com um Inconsistent indentation: 3 spaces were used for indentation, but the rest of the document was indented using 2 spaces.
    Isso pode também ser um pouco incômodo.

  • É bom para desenvolvedores, mas ruim para os designers
    Minha opinião neste ponto é que isso não é um problema. No conceito moderno de equipes ágeis temos equipes multidisciplinares, onde há especialistas em determinados assuntos mas todos têm uma boa compreensão do todo e de como as partes se integram. Assim como é interessante que os programadores conheçam HTML e CSS, também é interessante para o designers conhecerem ERb, Haml e entenderem pelo menos um mínimo do sentido das coisas. Afinal, depois de compreendido, Haml é muito simples.

  • O que realmente importa é a padronização institucionalizada em sua empresa
    Um desenvolvedor chamado John Miller escreveu que padronização institucionalizada é a justificativa usada para forçar muitas pessoas a utilizarem software "do mal" como IE6. Achei excelente esta declaração!
    Também li sobre alguns que praticam em sua empresa uma alternância de tecnologia e abordagem, utilizando por exemplo ERb em alguns projetos e Haml em outros. Eu pessoalmente não suporto uma mesma rotina por muito tempo e acredito que essa alternância, com o conhecimento e experiência que vai agregando, aumenta consideravelmente a motivação dos desenvolvedores.
    Acima de tudo, como mencionei antes, cada projeto apresenta necessidades específicas e a tecnologia mais adequada pode variar de projeto para projeto.

  • O futuro é incerto
    Alguns defendem, e eu concordo, que o futuro das estruturas XML (o que inclui HTML) tem tudo para ser longo, enquanto que o futuro de uma linguagem como Haml não pode ser garantido como algo que vá perdurar por muito tempo. A mesma incerteza envolveria CoffeeScript, que também não pode ainda competir de igual para igual com a "vitalidade" de JavaScript.

Referências


Para quem desejar (ou necessitar) aprofundar mais o conhecimento em Haml e conhecer um pouco sobre a experiência de outros desenvolvedores, abaixo vão alguns links que me foram úteis para este post:


Que 2013 seja um ano de muita criatividade, inovação e realização em nossas brilhantes carreiras!!

10 comentários:

  1. HAML is a two-edged sword - sure, it can be quite productive but it can also work against you if you've missed a 'tab'; this is further exacerbated if you're working with other devs and they mix their tabs, i.e. hard tabs and spaces! Nightmare.new.ensue!

    The reason I've particularly stopped using it is because it's not something every single front-end developer is aware/familiar with and when it comes to integrating work across teams etc. it's just easier to stick to good old HTML.

    That said, SASS is absolutely fantastic and many devs are getting on board with alternatives such as LESS as well etc.

    ResponderExcluir
  2. I agree with Michael de Silva, I don't see what HAML buys you. For starters, as Michael pointed out, it's proprietary to Rails (in a manner of speaking) and not all front-end devs will be able able to quickly ramp up. Secondly, it goes against most Ruby idioms and patterns in my opinion in that it's white-space dependent. And finally, what's wrong with ERB? Closing tags... really?

    ResponderExcluir
  3. Indeed Nathan. Also Daniel, for the above reason I'd strongly suggest not wasting time 'porting' over to HAML. For any decently mature apps, that's a lot of markup to 'reformat' (even with resources such as http://html2haml.heroku.com). The headaches related to maintaining a white-space dependent markup/DSL(?) out-weight any benefits that HAML may provide.

    So what does HAML buy you? The argument here is that you type less - but is this such an issue when certain editors helps with lot of the boilerplate, i.e. TextMate and it's fantastic bundles.

    Also the current trend is for Rails to serve up an API with the apps as client-side running your choice JS framework - as I recall, there's little potential for HAML in these. HAML's alternative in JS land, as an example, would be Node's Jade template (http://jade-lang.com/)... but I digress.

    ResponderExcluir
  4. I totally agree about the pain of dealing with white-space-as-syntax and being an obstacle to collaboration.

    However, having had to deal with HAML in existing codebases, I have found one benefit: it's so painful to do anything complex in HAML that I wind up moving more things into helper methods and partials, which is kind of a nice, if sightly forced, refactoring :-)

    ResponderExcluir
  5. IMHO, HAML isn't worth it if you (and everyone else who is going to need to grok the code) is already familiar with HTML. That is usually the case. It doesn't buy you much, and presents another learning hurdle.

    SASS/LESS/etc. on the other claw, ARE worth it, even if everybody is thoroughly familiar with CSS. Why? Because in this case, it DOES buy you enough to be well worth the learning hurdle. You can finally do a lot of the DRY-ing up that you can do in HTML with partials (or generated HTML), calculations, elimination of tons of boilerplate, etc.

    ResponderExcluir
  6. Hassan, I've heard that argument before, but I think it's a bad one. Relying on the technology to enforce good coding practices seems like the wrong way to go. I'd recommend using decorators (ex: draper gem) which set a better standard of pulling logic out of the view.

    ResponderExcluir
  7. Another point to be made is that HTML is going to be around for the forceable future, while HAML... who knows. XML uses the same basic syntax as HTML, so expect to see them brackets for a while. I'm not against syntax beautifiers... for example, I like CoffeeScript (though am not sure about it's shelf life either), but I've wasted lots of time running into dumb issues with HAML and trying to Google an answer for them. If it were my decision, I'd stay away from it.

    ResponderExcluir
  8. @Nathan - it wasn't an argument for using HAML. I wouldn't choose to use HAML in a project nor would I ever suggest migrating an existing app to it.

    But if you're stuck with it, make the best of it :-)

    Decorators are a whole other area of discussion...

    ResponderExcluir
    Respostas
    1. As a pedantic nit, you did claim a benefit in using HAML, which is the basis of an argument. Note, I didn't suggest you're advocating for it's use. And decorators do dovetail into your point about pulling logic out of the view -- yet they're a better pattern than relying on HAML to pain you into it.

      Excluir
    2. My use of the word "benefit" in that context was (intended to be) equivalent to "we have a flat tire and no spare, but the view here is awesome!".

      Note: the last part of that sentence is not intended to imply any benefit in flat tires. :-)

      Whatevs.

      Excluir