HAML в Rails

октября 2, 2011  |  Published in ClientSide, Ruby Gems, Ruby on Rails, Ruby on Rails 3, View  |  11 Comments

haml logoHAML — очень удобный язык разметки который призван заменить HTML. HAML это также шаблонизатор, который компилирует код на HAML + Ruby  в HTML, который представляется пользователю.

Мне надоел стандартный ERB, надоели закрывающие теги, надоело, что порой бывает сложно понять что во что вложено, и я решил полностью перебраться на HAML. Если вы еще не слышали о HAML, то это не означает, что HAML — это что-то экзотическое, напротив, HAML использует большинство Rails разработчиков, так активно используют, что даже удивились, почему Rails Core Team невключили HAML в Raila 3.1. как шаблонизатор по умолчанию.

Начать работу с HAML совсем просто!

1. Создайте приложение на Rails:

$ rails new hamlapp

2. Добавьте haml-rails в Gemfile вашего приложения:

#Gemfile
source 'http://rubygems.org'

gem 'rails', '3.0.9'
gem 'sqlite3'
gem 'haml-rails'

$bundle install
3. Изучайте HAML!

HAML очень прост!
Вместо <tag></tag> или <tag  /> вы должны использовать просто %tag.

Свойства тегов задаются внутри фигурных скобок, чем объявление свойств очень напоминает синтаксис хэша. <p id=»super_id»> </p> в HAML будет выглядеть так: %p{:class => «some_class», :id => «super_id»} или даже так: %p.some_class#super_id — это специальный синтаксис для классов и айдишников.

В случае, когда речь идет о <div>’ах, HAML вообще неотразим:
<div id=»my-id»> … </div> = #my-id
<div> … </div> = .my-class
<div, id=»my-id»> … </div> = #my-id.my-class

Для выполнения Ruby кода необходимо вместо скобок типа <% ruby %> использовать знак минуса:

- @articles.each do |article|
  -#ruby

А для вставки результата в страницу — знак равно, вместо <%= ruby %>:

- @articles.each do |article|
  = link_to article.title, article

Вложенность тегов, как и в YAML определяется через количество отступов, их должно быть парное количество.

Давайте напишем совсем простое представление совсем простого приложения для закрепления материала:

$ rails g scaffold Post title:string description:string content:text author:string site_url:string

      invoke    haml
      create      app/views/posts
      create      app/views/posts/index.html.haml
      create      app/views/posts/edit.html.haml
      create      app/views/posts/show.html.haml
      create      app/views/posts/new.html.haml
      create      app/views/posts/_form.html.haml

Вот пример того, как вяглядят стандартные файлы представления:

-#./app/views/posts/index.html.ham
%h1 Listing posts

%table
  %tr
    %th Title
    %th Description
    %th Content
    %th Author
    %th Site url
    %th
    %th
    %th

  - @posts.each do |post|
    %tr
      %td= post.title
      %td= post.description
      %td= post.content
      %td= post.author
      %td= post.site_url
      %td= link_to 'Show', post
      %td= link_to 'Edit', edit_post_path(post)
      %td= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete

%br

= link_to 'New Post', new_post_path

Давайте перепишем макет, который был сгенерирован в формате ERB. Вместо:

<!--- ./app/layouts/application.html.erb --->
<!DOCTYPE html>
<html>
  <head>
    <title>Hamlapp</title>
    <%= stylesheet_link_tag :all %>
    <%= javascript_include_tag :defaults %>
    <%= csrf_meta_tag %>
  </head>
  <body>

    <%= yield %>

  </body>
</html>

Мы cделаем вот, что:

-#это HAML комментарий, которого в HTML видно не будет
/а это HTML комментарий
!!!
%html
  %head
    %title Hamlapp
    = stylesheet_link_tag :all
    = javascript_include_tag :defaults
    = csrf_meta_tag
  %body
    = yield

Теперь давайте перепишем index.html.haml в бестабличном стиле:

#content
  %h1 Listing posts
  - @posts.each do |post|
    %div[post]
      %b Title:
      = post.title
      %br
      %b Description:
      = post.description
      %br
      %b Content:
      = post.content
      %br
      %b> Author:
      = post.author
      %br
      %b Site:
      = link_to post.site_url
      %br
      .controls
        = link_to 'Show', post
        = link_to 'Edit', edit_post_path(post)
        = link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete

  %br

  = link_to 'New Post', new_post_path

Вот эта конструкция — %div[post] позволяет генерировать такой код:

<div class='post' id='post_1'>
...
</div>

<div class='post' id='post_2'>
...
</div>

...

Думаю, этого вам будет вполне достаточно, ну а если нет, то вот вам несколько полезных ссылок:

Если нет никакой разницы — зачем писать больше?

Tags: , , ,

Responses

  1. ruslan says:

    октября 2, 2011 at 22:12 (#)

    haml медленный

  2. admin says:

    октября 2, 2011 at 22:34 (#)

    ruslan, HAML быстрее некоторых других шаблонизаторов, а проблемы с производительностью рендеринга отпадают при кешировании.

  3. Igas says:

    октября 2, 2011 at 22:37 (#)

    Хорош для layout’ов, но ужасен для inline элементов. IMHO

  4. andy says:

    октября 3, 2011 at 12:57 (#)

    Yaml Ain’t Markup Language. Соответственно HAML — не его диалект. А так всё хорошо.

  5. admin says:

    октября 3, 2011 at 15:19 (#)

    andy, спасибо, таки да, не диалект YAML, исправил.

  6. says:

    октября 4, 2011 at 23:44 (#)

    В копилку полезностей для haml —

  7. Игорь Александров says:

    октября 5, 2011 at 13:45 (#)

    Если вы используете Rails 3, то попробуйте Slim () и забудьте о Haml.

  8. Vetal4eg says:

    октября 7, 2011 at 02:31 (#)

    В хамл можно как и в ерб вставить простой хтмл?

  9. admin says:

    октября 7, 2011 at 08:13 (#)

    Vetal4eg, да, можно, нужнотолько использовать фильтр :erb, например:

    #wrapper
      :erb
        <div>
          ....
        </div>
    

    Для простого текста можно использовать :plain, еще поддерживается markdown и еще несколько движков. В любом можно использовать #{…} Для вставки Ruby кода.

  10. says:

    июля 6, 2012 at 10:02 (#)

    Перед end не нужен минус, как и сам end. Просто пишите условие haml все сам закроет, код из примеров валидацию не пройдет.

  11. admin says:

    июля 6, 2012 at 11:44 (#)

    Действительно, в первых двух примерах облажался. Спасибо за сообщение — поправил.

Leave a Response

Для подсветки кода используйте BB - коды: [language]...[/language], где language может быть: ruby, javascript, css, html.