HAML/SASS

Немытченко Иван

HAML. Что это?

HTML Abstraction Markup Language

HTML

.
        <div class="article">
          <div class="title">
            HAML/SASS
          </div>
          <div class="author">
            Ivan Nemytchenko
          </div>
          <div class="article_body">
            Много интересного текста
          </div>
          <div class="actions">
            <a href="/articles/18">view</a>
          </div>
        </div>
        
Вот кусок HTML-кода. Он выглядит вполне невинно До тех пор пока..

RHTML

.
        <div class="article">
        <div class="title">
          <%= h @article.title %>
        </div>
        <div class="author">
          <%= h @article.author.name %>
        </div>
        <div class="article_body">
          <%= h @article.body %>
        </div>
        <div class="actions">
          <%= link_to 'view', article_path(@article)%>
          <% if @article.author == current_user -%>
            <%= link_to 'edit', edit_article_path(@article)%>
          <% end -%>
        </div>
        </div>
        
Scissors
в него не добавили динамику. Так выглядят классические шаблоны ERB в Rails. Код уже на так красив и строен. А это только маленький кусок от всей страницы. Примерно так же выглядят шаблоны в PHP, Django и других системах. По сути это надстройки над HTML. Но HTML не идеален. В нем полным полно дублирования. Давайте попробуем это исправить

Сносим закрывающие тэги

.
        <div class="article">
          <div class="title">
            <%= h @article.title %>
          <div class="author">
            <%= h @article.author.name %>
          <div class="article_body">
            <%= h @article.body %>
          <div class="actions">
            <%= link_to 'view', article_path(@article)%>
            <% if @article.author == current_user -%>
              <%= link_to 'edit', edit_article_path(@article)%>
        
да, и end у условия тоже

Сносим <>

.
        div class="article"
          div class="title"
            = h @article.title
          div class="author"
            = h @article.author.name
          div class="article_body"
            = h @article.body
          div class="actions"
            = link_to 'view', article_path(@article)
            -if @article.author == current_user
              = link_to 'edit', edit_article_path(@article)
        

Применим соглашения CSS

.
        div.article
          div.title
            = h @article.title
          div.author
            = h @article.author.name
          div.article_body
            = h @article.body
          div.actions
            = link_to 'view', article_path(@article)
            -if @article.author == current_user
              = link_to 'edit', edit_article_path(@article)
        

Сносим div-ы (HAML готов!)

.
        .article
          .title
            = h @article.title
          .author
            = h @article.author.name
          .article_body
            = h @article.body
          .actions
            = link_to 'view', article_path(@article)
            -if @article.author == current_user
              = link_to 'edit', edit_article_path(@article)
        

Компактный вариант

.
        .article
          .title= h @article.title
          .author= h @article.author.name
          .article_body= h @article.body
          .actions
            = link_to 'view', article_path(@article)
            -if @article.author == current_user
              = link_to 'edit', edit_article_path(@article)
        

Cравнение: RHTML

.
        <div class="article">
        <div class="title">
          <%= h @article.title %>
        </div>
        <div class="author">
          <%= h @article.author.name %>
        </div>
        <div class="article_body">
          <%= h @article.body %>
        </div>
        <div class="actions">
          <%= link_to 'view', article_path(@article)%>
          <% if @article.author == current_user -%>
            <%= link_to 'edit', edit_article_path(@article)%>
          <% end -%>
        </div>
        </div>
        
И еще раз сравним: RHTML

Сравнение: HAML

.
        .article
          .title
            = h @article.title
          .author
            = h @article.author.name
          .article_body
            = h @article.body
          .actions
            = link_to 'view', article_path(@article)
            -if @article.author == current_user
              = link_to 'edit', edit_article_path(@article)
        
HAML

Сравнение

Сравнение

Пример. HTML

.
        <h1>Title</h1>
        <ul class="no-dots" id="mylist" style="color:red">
          <li class="item" id="item_3">fish</li>
          <li class="item selected" id="item_8">spoon</li>
          <li class="item" id="item_12">leg</li>
        </ul>
        

Пример. RHTML

.
        <h1><%= @list.title %></h1>
        <ul class="no-dots" id="mylist" style="color:red">
          <% @list.items.each do |item| -%>
            <li class="item <%= "selected" if item.selected? %>" 
              id="item_<%= item.id %>">
              <%= item.name %>
            </li>
          <% end -%>
        </ul>
        

Пример. HAML

.
        %h1= @list.title
        %ul.no-dots#mylist{ :style => "color:red" }
          -@list.items.each do |item|
            %li[item]{:class => 'selected' if item.selected? }
              = item.name
        

XML

.
        %one
          %two{:alpha => 'uno', :beta => (3+5)}
            %three something
        
.
        <one>
          <two alpha='uno' beta='8'>
            <three>something</three>
          </two>
        </one>
        

Фильтры

.
        .markdown
          :markdown
            Header
            =======
        
            Hello, *World*
        
.
        <div class="markdown">
          <p>
            <h1>Header</h1>
        
            <p>Hello, <em>World</em></p>
          </p>
        </div>
        

Фильтры

Также есть возможность определить свои собственные фильтры.

Используем HAML

.
        gem install haml
        rails my_rails_app
        haml --rails my_rails_app
        
.
        haml = Haml::Engine.new("%p Haml code!")
        haml.render #=> "<p>Haml code!</p>\n"
        
.
        $ echo ".message Hello, World" | haml
          => '<div class="message">Hello, World</div>'
        

Python? PHP?

SASS

Syntactically Awesome StyleSheets

CSS -> SASS

.
        h1 {
          font-family: Arial;
          font-weight: bold;
          color: #550000;
          text-decoration: underline }
        ul#mylist {
          margin: 2px;
          width: 400px; }
        ul#mylist li {
          background-color: #FFFFAA;
          color: #550000;
          text-decoration: underline; }
        

CSS -> SASS. Убираем кавычки и точки с зяпятой

.
        h1
          font-family: Arial
          font-weight: bold
          color: #550000
          text-decoration: underline
        ul#mylist 
          margin: 2px
          width: 400px 
        ul#mylist li 
          background-color: #FFFFAA
          color: #550000
          text-decoration: underline
        

CSS -> SASS. Переносим двоеточия (SASS готов!)

.
        h1
          :font-family Arial
          :font-weight bold
          :color #550000
          :text-decoration underline
        ul#mylist 
          :margin 2px
          :width 400px 
        ul#mylist li 
          :background-color #FFFFAA
          :color #550000
          :text-decoration underline
        

CSS -> SASS. Доводка

.
        =common_style
          :color #550000
          :text-decoration underline
        h1
          :font
            :family Arial
            :weight bold
          +common_style
        ul#mylist 
          :margin 2px
          :width 400px 
          li 
            :background-color #FFFFAA
            +common_style
        

Типовое использование

.
        #main
          :width 97%
          p, div
            :font-size 2em
            a
              :font-weight bold
          pre
            :font-size 3em
        

Типовое использование

.
        #main {
          width: 97%; }
          #main p, #main div {
            font-size: 2em; }
            #main p a, #main div a {
              font-weight: bold; }
          #main pre {
            font-size: 3em; }
        

Типовое использование

.
        a
          :font-weight bold
          :text-decoration none
          &:hover
            :text-decoration underline
          &:visited
            :font-weight normal
        

Типовое использование

.
        a {
          font-weight: bold;
          text-decoration: none; }
          a:hover {
            text-decoration: underline; }
          a:visited {
            font-weight: normal; }
        

Арифметика

.
        !main_width = 10
        !unit1 = em
        !unit2 = px
        !bg_color = #a5f39e
        
        #main
          :background-color = !bg_color
          p
            :background-color = !bg_color + #202020
            :width = !main_width + !unit1
          img.thumb
            :width = (!main_width + 15) + !unit2
        

Арифметика

.
        #main {
          background-color: #a5f39e; }
          #main p {
            background-color: #c5ffbe;
            width: 10em; }
          #main img.thumb {
            width: 25em; }
        

Mixins

.
        =large-text
          :font
            :family Arial
            :size 20px
            :weight bold
          :color #ff0000
        
        .page-title
          +large-text
          :padding 4px
          :margin
            :top 10px
        

Mixins

.
        .page-title {
          font-family: Arial;
          font-size: 20px;
          font-weight: bold;
          color: #ff0000;
          padding: 4px;
          margin-top: 10px;
        }
        

Авторы

Ссылки