Pull to refresh

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

Reading time5 min
Views75K
Давно хотел попробовать 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
Tags:
Hubs:
+55
Comments68

Articles