Давно хотел попробовать Haml, но всё не было времени. Но вот недавно обнаружил новый шаблонизатор, который мне сразу понравился. По словам создателей, он взял лучшее от Jade и Haml. Основная задача — сократить объем кода, при этом не делая его страшным и непонятным.
Вот так выглядит шаблон с использованием Slim:
Как и в Haml, форматирование вывода идёт по отступам. Вместо конструкции <%= %> используется знак =. Для вычислений без вывода в html (например, для if и for), ставится знак -.
В отличие от Haml'a, тут нет знака %, которым выделяются теги. Их можно сразу писать как есть. По сути, это просто HTML без <> скобок, в котором используются отступы для обозначения вложенных элементов. К слову, количество отступов — на ваш выбор, но не менее одного.
Обозначать id и class можно вот так:
Для сравнения с Haml:
Кроме того, Slim допускает несколько вариантов синтаксиса::
Еще одна приятная штука — если в атрибуте не указаны кавычки, будет использована переменная. Из примера парой строчек выше можно увидеть, что используется переменная page_header_class.
Если функция возвращает false, атрибут вообще не будет выведен в html (как и в Haml):
Можно использовать интерполяцию как в строках Ruby:
Мне очень нравится, как работают комментарии. Если у вас имеется блок кода, который надо закомментить, достаточно добавить всего одну строку, которая повлияет на весь блок.
Стоит учесть, что метод render по-умолчанию фильтрует вывод, поэтому перед ним надо ставить двойной знак равенства, чтобы escape_html не сработал дважды.
И вот что можно с ним делать:
Возможно, прочитав первый пример, у вас возник вопрос — откуда берется переменная 'title'? Slim сам пытается её найти несколькими способами.
Лично мне такой режим не понравился, но может именно вам он придется по вкусу.
Шаблоны в рельсах кешируются, поэтому по скорости они будут отставать от стандартного Erb лишь при первом обращении к ним. Вот сравнительная таблица, которая показывает, что Slim уж точно не будет узким местом в вашем приложении:
Есть 2 варианта. Первый — без добавления генераторов шаблонов (для создания, например, Scaffold’ов). Второй — с генераторами.
Не стоит забывать, что для использования 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
Вот так выглядит шаблон с использованием 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’ов). Второй — с генераторами.
Затем нужно прописать в консоли bundle install для установки выбранных гемов.# Если вам просто нужен Slim gem 'slim' # Если вам нужен Slim и генераторы Scaffold'ов gem 'slim-rails'
Не стоит забывать, что для использования 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