Search
Write a publication
Pull to refresh

Rails: от ERb к Haml

Всем хорошо известно, что родным способом генерации всевозможных HTML страничек в рельсах является использование Ruby Templating, ERb. Честно признаюсь, до недавнего времени считал его единственным и вполне приемлемым. Но все изменилось, когда я познакомился с Haml. В данной статье я собираюсь рассказать об этом знакомстве.

Идея ERb достаточно проста – вы пишите HTML-код, попутно включая в него Ruby-вставки, которые в последствии будут заменены на результат вычисления выражения во вставке. Рассмотрим небольшой пример. Пусть у нас есть модель статей (Article). Код для вывода списка статей традиционно содержится в файле index.html.erb. Файл может выглядеть следующим образом:

Copy Source | Copy HTML
  1. <%- @articles.each do |article| -%>
  2.   <div class="article">
  3.     <div class="date"><%= l article.created_at.to_date -%></div>
  4.     <h2><%= link_to h(article.title), article_path(article) -%></h2>
  5.     <div class="summary"><%= h article.summary -%></div>
  6.   </div>
  7. <%- end -%>


Если у вас какой-нибудь более-менее продвинутый дизайн, например, если вы задумали выводить красивую рамочку с закругленными краями при наведении на статью, то код может раздуться еще сильнее – могут появиться пустые DIV'ы для вывода каждой стороны этой самой рамочки (естественно, что к этому всему еще должен подключаться соответствующий CSS). В итоге код будет захламлен бесконечными открывающимися и закрывающимися HTML-тегами. Да и чем больше текста, тем сложнее его обрабатывать различным процессорам, вроде того же ERb.
Еще один момент, который мне не очень нравится, – это то, что без ужаса на код конечной HTML-страницы смотреть невозможно. Когда какой-нибудь шаблонн содержит другие, например, перебирает какую-нибудь коллекцию объектов и отображает соответствующий partial для каждого ее элемента (render :partial => 'article', :collection => @articles), а потом это все еще и в лэйаут заворачивается, то в итоге код странички превращается в полную кашу – пустые строки, разные уровни выравнивания, скачущие теги, лишние пробелы. Некоторых проблем можно избежать, но для этого разработчику нужно тщательно следить за расстановкой минусов в Ruby-вставках (<%- @articles.each do | article| -%>, <%= h article.summary -%>), что тоже не доставляет большого удовольствия.
Ладно, хватит о грустном, пора переходить в более лаконичному и красивому способу построения шаблонов – Haml. Постоянно натыкался на это поначалу непонятное слово в сети, много чего слышал о нем хорошего, но как-то все не доходило до дела. И вот совсем недавно в связи с наличием свободного времени все же решил с ним познакомиться поближе. Все, что необходимо сделать, чтобы втянуться в этот замечательный язык построения шаблонов, – это пройти пятиминутный обучающий курс на сайте.
Давайте попробуем перевести приведенный выше файл index.html.erb в Haml. Для этого переименуем его расширение в haml, получим index.html.haml.
Немножко отвлекусь и скажу для яблочных ребят и любителей TextMate, что для комфортной работой с Haml-файлами необходимо установить соответствующий пакет:

Copy Source | Copy HTML
  1. cd ~/"Library/Application Support/TextMate/Bundles/"
  2. svn co "http://macromates.com/svn/Bundles/trunk/Bundles/Ruby Haml.tmbundle"


В VIM'е у меня соответствующий синтаксический файл уже был, так что с ним проблем не было.
Идем дальше, теперь давайте установим gem:

Copy Source | Copy HTML
  1. $ sudo gem install --no-ri haml


Ну и наконец Haml-ализуем наше рельсовое приложение:

Copy Source | Copy HTML
  1. $ haml --rails /path/to/our/rails/application


Ничего страшного данная команда не делает, а просто устанавливает маленький плагин в папку vendor/plugins. Итак, дело сделано. Теперь все шаблоны с расширением haml будут обрабатываться процессором Haml. Стоп. Но ведь пока наш единственный Haml-шаблон содержит код для ERb, давайте это исправим:

Copy Source | Copy HTML
  1. - @articles.each do |article|
  2.   %div{:class => "article"}
  3.     %div{:class => "date"}= l article.created_at.to_date
  4.     %h2= link_to h(article.title), article_path(article)
  5.     %div{:class => "summary"}= h article.summary


Согласитесь, уже сейчас код выглядит намного симпатичнее. Это особо ощутимо на больших шаблонах вроде того же лэйаута. Чуть ниже мы перепишем его в еще более короткой форме, а пока расскажу о том, что же мы сделали (для полного овладения всеми фишками Haml настоятельно советую прочитать небольшую и такую же лаконичную, как и сам Haml, документацию на сайте проекта).
Первая строчка начинается со знака минус. Как вы наверное уже догадались, данная строчка аналогична <% %>, она не генерирует никакого HTML, а служит для выполнения различного рода вспомогательного Ruby-кода, в данном случае для организации цикла.
Хочу заметить, что для Haml очень важны уровни выравнивания кода, именно по ним Haml-процессор определяет, где заканчивается соответствующие выражение или HTML-тег. Благодаря этой замечательной особенности Haml в коде пропадают закрывающиеся конструкции вроде ключевого слова end.
Все последующие строки нашего шаблона начинаются со знака процента, который предназначен для генерации тегов. Имя тега может быть абсолютно любым. После имени в фигурных скобкам может идти определение атрибутов тега в нотации схожей с Ruby-хешами. Ну и завершает все это дело знак равенства, сигнализирующий о начале Ruby-кода. Есть еще множество других вариантов вместо знака равенства, например, если добавить еще один знак равенства, после этого весь оставшийся хвост будет восприниматься как Ruby-строка в двойных кавычках, которые теперь писать уже не надо.
Перейдем к обещанному сокращению кода. Поскольку такие атрибуты тега как class и id используются достаточно часто, Haml позволяет задавать их следующим образом (очень похоже на задание классов и идентификаторов CSS):

Copy Source | Copy HTML
  1. - @articles.each do |article|
  2.   %div.article
  3.     %div.date= l article.created_at.to_date
  4.     %h2= link_to h(article.title), article_path(article)
  5.     %div.summary= h article.summary


Аналогично будет с атрибутом id, только вместо точки будет решетка. Если необходимо указать несколько классов у одного тега, то их смело можно перечислять через точку, как это мы обычно делаем в CSS.
Но и это еще не все! Не побоюсь заявить, что тег DIV является самым распространенным средством верстки современных сайтов, поэтому он встречается довольно часто. В связи с этим Haml позволяет его опускать. Вот, что из этого может выйти:

Copy Source | Copy HTML
  1. - @articles.each do |article|
  2.   .article
  3.     .date= l article.created_at.to_date
  4.     %h2= link_to h(article.title), article_path(article)
  5.     .summary= h article.summary


Предлагаю прокрутить страничку выше и сравнить с тем, с чего мы начали. Не знаю как у вас, но у меня после такого знакомства сразу же появилось желание отучить один из небольших проектов нашей компании от ERb и подсадить его на Haml, что я успешно и сделал, при этом получил массу эстетического удовольствия от сокращения кода и приведения его к лаконичному и красивому виду. Планирую все последующие проекты разрабатывать с использованием этого замечательного языка.
Ну и напоследок хочется сказать, что и для построения CSS есть такая штука как Sass, причем она уже у вас установлена, так как идет в комплекте с Haml, синтаксис очень схож. Теперь можно поместить шаблоны с расширением sass в директорию public/stylesheets/sass, после чего соответствующие CSS-файлы будут созданы и положены в папку на уровень выше, где им и место. Честно говоря, с Sass я поиграться не пробовал, так что за примерами сразу отсылаю вас к соответствующей документации.
_________
Текст подготовлен в ХабраРедакторе
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.