Шаблонизатор Slim — альтернатива Haml'y

    Давно хотел попробовать Haml, но всё не было времени. Но вот недавно обнаружил новый шаблонизатор, который мне сразу понравился. По словам создателей, он взял лучшее от Jade и Haml. Основная задача — сократить объем кода, при этом не делая его страшным и непонятным.

    Вот так выглядит шаблон с использованием Slim:
    doctype html
    html
      head
        title Slim Examples
        meta name="keywords" content="template language"
    
      body
        h1 Markup examples
        #content.example1
          p Nest by indentation
    
        = yield
    
        - unless items.empty?
          table
            - for item in items do
              tr
                td = item.name
                td = item.price
        - else
          p No items found
    
        #footer
          | Copyright © 2010 Andrew Stone
    
        = render 'tracking_code'
    
        script
          | $(content).do_something();


    Как и в Haml, форматирование вывода идёт по отступам. Вместо конструкции <%= %> используется знак =. Для вычислений без вывода в html (например, для if и for), ставится знак -.

    В отличие от Haml'a, тут нет знака %, которым выделяются теги. Их можно сразу писать как есть. По сути, это просто HTML без <> скобок, в котором используются отступы для обозначения вложенных элементов. К слову, количество отступов — на ваш выбор, но не менее одного.

    Список всех операторов:

    | Вертикальная черта сообщает шаблонизатору, что нужно просто откопировать линию. При этом все "опасные" символы фильтруется.
    ' Одиночная скобка работает как и предыдущий оператор, но добавляет в конце пробел.
    - Дефис работает как и в Haml, используется для циклов, условий и прочего, в чем вы раньше использовали <% ... %>
    = Знак равенства работает как <%= ... %>, выводя содержимое в html
    =' Работает как и предыдущий оператор, при этом добавляя в конец пробел.
    == Работает как и знак равенства, но выводит текст "как есть", без обработки методом escape_html
    ==' Тоже самое, что и выше, но добавляет в конце пробел.
    / Знак комментария. Код не будет выполнен и не попадет в html вообще.
    /! Знак для html комментариев (<!-- -->), которые попадут в вывод.


    Атрибуты и комментарии

    Обозначать id и class можно вот так:
    blockquote id="quote-#{@quote.id}" class="quote"
      p class="title" = @quote.title
      p style="padding:1em;" = @quote.body


    Для сравнения с Haml:
    %blockquote{:id => "quote-#{@quote.id}", :class => "quote"}
      %p{:class="title"}= @quote.title
      %p{:style => "padding:1em;"}= @quote.body


    Кроме того, Slim допускает несколько вариантов синтаксиса::
    / Эти две линии идентичны. Первый вариант синтаксиса, наверно, знаком вам по Haml'у 
    #nav.top
    div id="nav" class="top"
    
    / Допускается писать любой из этих вариантов
    h1 class=page_header_class = page_header
    h1{class=page_header_class} = page_header
    h1[class=page_header_class] = page_header
    h1(class=page_header_class) = page_header


    Еще одна приятная штука — если в атрибуте не указаны кавычки, будет использована переменная. Из примера парой строчек выше можно увидеть, что используется переменная page_header_class.
    # Можно писать и так, и так.
    a href="#{url_for @user}" = @user.name
    # Во втором случае не надо писать конструкцию "#{...}"
    a href=url_for(@user) = @user.name


    Если функция возвращает false, атрибут вообще не будет выведен в html (как и в Haml):
    option value="Slim" selected=option_selected?("Slim") # -> <option value="Slim"></option>


    Можно использовать интерполяцию как в строках Ruby:
    body
      h1 Приветствуем, #{current_user.name}
      | С помощью двойных скобок #{{content}} выводится как есть, без фильтрации методом escape_html.



    Мне очень нравится, как работают комментарии. Если у вас имеется блок кода, который надо закомментить, достаточно добавить всего одну строку, которая повлияет на весь блок.
    # весь этот блок ниже закомментирован и не будет выведен
    /.comments
      - @comments.each do |comment|
        == render comment


    Стоит учесть, что метод render по-умолчанию фильтрует вывод, поэтому перед ним надо ставить двойной знак равенства, чтобы escape_html не сработал дважды.

    Режим Logic-less

    Slim::Engine.set_default_options :sections => true

    И вот что можно с ним делать:
    / Автоматическая проверка переменной на false и empty?, если прошла то h1 будет выведен
    - article
      h1 = title


    / Обратная проверка, если article удовлетворяет условиям false или empty? то блок будет выведен
    -! article
      p Статья не найдена


    Возможно, прочитав первый пример, у вас возник вопрос — откуда берется переменная 'title'? Slim сам пытается её найти несколькими способами.
    / If article.respond_to?(:title)
    - article
      / Исполняется article.send(:title)
      h1 = title

    / If article.respond_to?(:has_key?) and article.has_key?(:title)
    - article
      / Выводится переменная article[:title]
      h1 = title

    / If article.instance_variable_defined?(@title)
    - article
      / Будет выведена классовая переменная с помощью article.instance_variable_get @title
      h1 = title

    Лично мне такой режим не понравился, но может именно вам он придется по вкусу.

    Что насчет производительности

    Шаблоны в рельсах кешируются, поэтому по скорости они будут отставать от стандартного Erb лишь при первом обращении к ним. Вот сравнительная таблица, которая показывает, что Slim уж точно не будет узким местом в вашем приложении:
    # Linux + Ruby 1.9.2, 1000 iterations
                          user     system      total        real
    (1) erb           0.680000   0.000000   0.680000 (  0.810375)
    (1) erubis        0.510000   0.000000   0.510000 (  0.547548)
    (1) fast erubis   0.530000   0.000000   0.530000 (  0.583134)
    (1) slim          4.330000   0.020000   4.350000 (  4.495633)
    (1) haml          4.680000   0.020000   4.700000 (  4.747019)
    (1) haml ugly     4.530000   0.020000   4.550000 (  4.592425)
    
    (2) erb           0.240000   0.000000   0.240000 (  0.235896)
    (2) erubis        0.180000   0.000000   0.180000 (  0.185349)
    (2) fast erubis   0.150000   0.000000   0.150000 (  0.154970)
    (2) slim          0.050000   0.000000   0.050000 (  0.046685)
    (2) haml          0.490000   0.000000   0.490000 (  0.497864)
    (2) haml ugly     0.420000   0.000000   0.420000 (  0.428596)
    
    (3) erb           0.030000   0.000000   0.030000 (  0.033979)
    (3) erubis        0.030000   0.000000   0.030000 (  0.030705)
    (3) fast erubis   0.040000   0.000000   0.040000 (  0.035229)
    (3) slim          0.040000   0.000000   0.040000 (  0.036249)
    (3) haml          0.160000   0.000000   0.160000 (  0.165024)
    (3) haml ugly     0.150000   0.000000   0.150000 (  0.146130)
    
    (4) erb           0.060000   0.000000   0.060000 (  0.059847)
    (4) erubis        0.040000   0.000000   0.040000 (  0.040770)
    (4) slim          0.040000   0.000000   0.040000 (  0.047389)
    (4) haml          0.190000   0.000000   0.190000 (  0.188837)
    (4) haml ugly     0.170000   0.000000   0.170000 (  0.175378)
    
    1. Рендер некешированной страницы при первом обращении.
       Его можно активировать, используя параметр slow=1.
    
    2. Кешированный тест. Шаблон предварительно парсится.
       Код Ruby не компилируется и может быть выполнен в любое время.
       Этот бенчмарк испольует стандартное API шаблонов.
    
    3. Компилированный тест. Шаблон также предварительно парсится,
       но кроме того, код Ruby компилируется в отдельный метод.
       Это самый быстрый тест, потому что в нем тестируется лишь
       скорость выполнения самого кода.
    
    4. Компилированный Tilt-бенчмарк. Шаблон компилируется с помощью Tilt,
       что даёт более точные результаты производительности в режиме Продакшена
       в таких фреймворках как Sinatra, Ramaze and Camping.

    Как установить

    Есть 2 варианта. Первый — без добавления генераторов шаблонов (для создания, например, Scaffold’ов). Второй — с генераторами.
    # Если вам просто нужен Slim
    gem 'slim'
    
    # Если вам нужен Slim и генераторы Scaffold'ов
    gem 'slim-rails'
    Затем нужно прописать в консоли bundle install для установки выбранных гемов.

    Не стоит забывать, что для использования Slim ваши файлы должны иметь расширение .slim. То есть, файл index.html.erb будет выполнен шаблонизатором Erb, а index.html.slim — соответственно, Slim.

    Полезные ссылки

    slim-lang.com— официальная страница
    github.com/stonean/slim — страница на Github
    github.com/fredwu/haml2slim — конвертатор Haml в Slim
    github.com/fredwu/ruby-slim-tmbundle — бандл для TextMate
    github.com/bbommarito/vim-slim — файлы для Vim
    Поделиться публикацией

    Похожие публикации

    Комментарии 68
      +1
      Очень! Очень хочу такое на Python.
        +2
        Эта штука сама по себе «со вкусом питона», по-моему. :)
          +1
          угу, потому что indent based, бррр
            +6
            А мне нравится.
              0
              лаконичность мне тоже нравится. но мне комфортней cчитатать пробелы — оформлением кода, сущностью от самого кода вобщем-то независимой, а потому пайтона и хамла стараюсь избегать.
              мне все это напоминает #region и #endregion от майкросовфта для фолдинга кода в msvs:)
                0
                Но вы ведь в любом случае оформляете код отступами. Если отступы уже используются для оформления блоков кода — мне показалось очень логичным этим и ограничиться.

                Кроме того, indent based подход гарантирует, что вы при чтении кода не «провтыкаете» важный оператор из-за того, что особое расположение звезд заставило вашего коллегу записать его в одной строке с другим оператором. А еще он делает код, написанный разными программистами, более-менее одинаковым. По крайней мере визуально. :) Минус одно соглашение, о котором команда будет спорить, +10 к скиллу «чтение чужого кода». Здорово же.
          +3
          А давайте портируем! Я с удовольствием.
            +1
              0
              Замечательно!
              Хоть синтаксисом он проигрывает Slim'у, наличие внутри него AST очень радует.
              0
                0
                держи yammy
                –11
                Вы скоро и html забудете, и javascript, бедные бедные рубисты. Что за мания создавать новые сущности.
                  +9
                  КПД?
                    –10
                    еще понимаю, в простых наколенных проектах, но в больших, где работает группа людей мне кажется выигрыш стремится к 0.
                      +7
                      Вам кажется.
                        +4
                        Жму руку уважения рубистам! Столько минусов в комментарий, и не одного в карму! Это по человечески,!
                          0
                          К слову, раньше я искал способ повысить производительность при верстке, начал использовать zen-coding — к синтаксису привыкаешь очень быстро. А он очень похож на объект статьи.

                          Посмотрите на хамл и слим с другой стороны. Как параллель люди придумали посудомоечные машины, но не разучились мыть посуду руками

                        +8
                        Я, например, уже пару лет как забыл html в пользу haml, css в пользу sass/compass и с полгода назад начал забивать на джаваскрипт в пользу кофескрипта. Чувствую себя при этом очень сухо и комфортно. Очень возрасла скорость разработки и качество кода.

                        Бедный я!
                        +3
                        Кажется я начинаю забывать, с какой стороны нужно открывающую скобку ставить, а с какой закрывающую в html… ох беда, беда.
                          +4
                          А еще мы забудем, как самим реализовывать авторизацию, аутентификацию, рисование формочек, прикрепление файлов, как писать на чистом SQL, как использовать операторы for и while и как возиться с натройкой деплоя. И многое другое. Это такая печаль.
                            0
                            for и while заменяем на .each и .times? Я правильно понял?
                              0
                              В подавляющем большинстве случаев — да.
                            +6
                            «Бедные, бедные рубисты» (с)
                            достойно башорга ))
                              0
                              Такой тонкий юмор не все поймут.
                            0
                            Не думал что лучше хамла что-то придумают. Но кажется это действительно вкусно.
                            В следующем проекте обязательно.
                              +2
                              Спасибо за перевод. Только, по-моему, ты путаешь скобки с кавычками. Везде где были кавычки, ты назвал из скобками.
                                0
                                Не везде, только в двух местах -).

                                Ночью писал, видимо, просмотрел. Спасибо за корректировку.
                                0
                                Использую уже месяца 2 в проектах на Rails 3.
                                В свободное время пытаюсь заставить работь slim в Rails 2.3. Есть некоторые продвижения, но пока до конца не получилось.
                                  0
                                  Кажется, хорошая штука в пользу еще большего улучшения производительности программиста. И очень удивил бенчмарк, я не думал, что haml в сыром и готовом виде настолько медленнее выполняется. Заставляет задуматься, но, пожалуй, в любом случае быстрее любой CMS.
                                  Программисты ruby on rails всегда выбирают незначительный проигрыш в производительности программы за счет огромного выигрыша в производительности программиста и качества кода. Дешевле докупить железо, чем переплачивать гораздо бОльшие деньги за дополнительное время разработки. К счастью, для нас человекочасы дороже машинных часов).
                                    +1
                                    Кстати кто может пояснить причину такой медлительности хамла даже уже в скомпилированном виде?
                                      0
                                      И, дополню свой вопрос, если у меня деплой на nginx в production, то какой из бенчмарков наиболее близок к реальности

                                      Ps где вообще можно почитать про описанные автором 4 вида тестов

                                      Pps автору огромный респект узнал много нового
                                    –1
                                    А как на счет вложенных тегов?
                                      +2
                                      Всё просто же.

                                      ul
                                        li
                                          a href="/"
                                            img src="logo.png"
                                      
                                      # будет выведено в такой код:
                                      <ul>
                                        <li>
                                          <a href="/">
                                             <img src="logo.png" />
                                            </a>
                                        </li>
                                      </ul>
                                      0
                                      Обозначать id и class можно вот так:
                                      blockquote id="quote-#{@quote.id}" class="quote"
                                        p class="title" = @quote.title
                                        p style="padding:1em;" = @quote.body
                                      

                                      Для сравнения с Haml:
                                      %blockquote{:id => "quote-#{@quote.id}", :class => "quote"}
                                        %p{:class="title"}= @quote.title
                                        %p{:style => "padding:1em;"}= @quote.body
                                      

                                      Вы лукавите. В haml можно писать и так:

                                      %blockquote(id="quote-#{@quote.id}" class="quote")
                                        %p(class="title")= @quote.title
                                        %p(style="padding:1em;")= @quote.body
                                      
                                        0
                                        Я не лукавлю, разве мой способ неверен для хамла?

                                        В любом случае в Sass, как по мне, более чистый синтаксис.
                                          0
                                          в slim наверное =)
                                            0
                                            Всё, надо ложиться спать раньше)
                                            0
                                            Я к тому, что в хамле записывать значения атрибутов можно не менее удобно, чем в slim.
                                              0
                                              В slim на 2 скобочки в строке меньше. Разве не за это мы любим руби?) Но я согласен, улучшения незначительны. В новых проектах стоит попробовать, но в старых можно спокойно оставаться на haml.
                                            0
                                            А можно и
                                            %p.title опускав генеалоге слово класс
                                            И # для id
                                              0
                                              Опустив ненужное слово*

                                              Чертов айпад!
                                            0
                                            По работе вынужден использовать PHP + Smarty. Такие статьи хочется просто удалять )))
                                                0
                                                Он разве production ready? Судя по коммитам его еще в 2010 забросили.
                                              0
                                              Вам в PHP не хватает своих велосипедов?
                                                0
                                                Ссылку на indent-шаблонизатор в студию.
                                                  0
                                                  Будут. Не отчаивайтесь. Оно же любимое дело php-программеров изобретать и обсуждать кривые шаблонизаторы. При том что в самом PHP встроен шаблонизатор рекомендованный в качестве стандарта W3C еще в прошлом веке.
                                                    0
                                                    Можете не утруждать себя продолжением дискуссии. Вам сюда.
                                                    0
                                                0
                                                Эх, по прежнему если, например в теге p, где много много текста надо вставить ссылку, то ссылку надо писать на новой строке, разрывая по сути p
                                                  0
                                                  p
                                                      |' Текст со
                                                      'a href='page.html' ссылкой
                                                      | на другую страницу.
                                                  

                                                  Или как-то так.
                                                  0
                                                  Жаль в RubyMine поддержки нет
                                                    +1
                                                    примерно по этой причине (тогда причина — haml) выбор пал на vim. Два месяца позора — и можно программировать ))) (не к чему не призываю. it's my way)
                                                      0
                                                      Как обычно нет этих двух месяцев на заточить пилу осилять vim.
                                                      Поэтому я там выучил только, как править, сохранять и выходить -а на случай отсутствия на машине nano ;)
                                                        0
                                                        вы меня неправильно поняли.

                                                        Для vim быстро публикуется все новое. Подсветка и другие плюшки. vim можно при помощи 4 напильников и молотка превратить в IDE. Я об этом, а nano == notepad. Проще mc поставить и во внутреннем редакторе править.

                                                        cat ed sed тут не причем ))))

                                                          0
                                                          >Для vim быстро публикуется все новое. Подсветка и другие плюшки. vim можно при помощи 4 напильников и молотка превратить в IDE

                                                          Я в курсе

                                                          >а nano == notepad

                                                          Ну почти, в nano подсветка синтасиса есть ;)

                                                          >Проще mc поставить и во внутреннем редакторе править.

                                                          Чем проще? Тем, что для того, чтобы поправить файл придётся запускать mc?

                                                          >cat ed sed тут не причем ))))

                                                          А где я их упоминал?
                                                      0
                                                      Есть.
                                                        0
                                                        На момент появления комментария (полтора года назад) — не было
                                                      +1
                                                      По сути, это просто HTML без <> скобок, в котором используются отступы для обозначения вложенных элементов.

                                                      а если вместо отступов сделать скобочки, будет обратно похоже на Lisp :)
                                                        0
                                                        Не безъизвестный timpope уже внес поддержку slim в rails.vim
                                                          0
                                                          Ребят, может быть я что-то не понимаю, но автоматическое определение тэгов лично меня напрягает. Если в том же haml я могу однозначно определить тэг как

                                                          %title some text

                                                          то использование в slim конструкции

                                                          title some text

                                                          выглядит немного пугающе. А если я хочу начать строку со слова title или article или еще с какого-то слова, совпадающего с тэгом — это тоже автоматом будет определяться как текст и превращаться в тэг? Лично меня бы это очень огорчило.
                                                            0
                                                            просто текст в слиме будет писаться так:
                                                            | title some text
                                                              0
                                                              то есть — надо будет не тэги выделять, а обычный текст? :(
                                                                0
                                                                Только если этот текст пишется вне строки с тегом
                                                                Тоесть делается либо так

                                                                title some_title_text
                                                                

                                                                либо так

                                                                title
                                                                  | some_title_text
                                                                
                                                            0
                                                            А есть конвертер из Jade в Slim?

                                                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                            Самое читаемое