Introduction to Slim Templating Language

6 Min. Read
Aug 13, 2019

What is Slim?

Slim is a template language whose goal is to reduce the view syntax to the essential parts without becoming cryptic. It started as an exercise to see how much could be removed from a standard html template (<, >, closing tags, etc…). As more people took an interest in Slim, the functionality grew and so did the flexibility of the syntax. It is a fast, lightweight templating engine with support for Rails 3 and later. It has been heavily tested on all major ruby implementations.

Slim’s core syntax is guided by one thought: “What’s the minimum required to make this work”. As more people have contributed to Slim, there have been syntax additions influenced from their use of Haml and Jade. The Slim team is open to these additions because we know beauty is in the eye of the beholder.

Why use Slim?

  • Slim allows you to write very minimal templates which are easy to maintain and pretty much guarantees that you write well-formed HTML and XML
  • The Slim syntax is aesthetic and makes it more fun to write templates.
  • Since you can use Slim as a drop-in replacement in all the major frameworks it is easy to adopt.
  • The Slim architecture is very flexible and allows you to write syntax extensions and plugins.
  • Slim is speedy.It was developed right from the start with performance in mind.

Features of Slim

1) Elegant syntax

  • Short syntax without closing tags (Using indentation instead)
  • HTML style mode with closing tags
  • Configurable shortcut tags (# for <div id="..."> and . for <div class="...">)

2) Safety

  • Automatic HTML escaping by default
  • Support for Rails’ html_safe?

3) Extensible via the following plugins:

  • Logic less mode similar to Mustache
  • Includes
  • Translator/I18n

4) High performance

  • Comparable speed to ERB/Erubis
  • Streaming support in Rails

5) Supported by all major frameworks (Rails, Sinatra, …)

6) Full Unicode support for tags and attributes

Getting Started

Install Slim as a gem:

1
gem install slim

or include Slim in your Gemfile with

1
gem 'slim-rails'

or require it with

1
require 'slim'

Syntax example

Here’s a quick example to demonstrate what a Slim template looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
doctype html
html
  head
    title Slim Examples
    meta name="keywords" content="template language"
    meta name="author" content=author
    link rel="icon" type="image/png" href=file_path("favicon.png")
    javascript:
      alert('Slim supports embedded javascript!')

  body
    h1 Markup examples

    #content
      p This example shows you how a basic Slim file looks.

    == yield

    - if items.any?
      table#items
        - for item in items
          tr
            td.name = item.name
            td.price = item.price
    - else
      p No items found. Please add some inventory.
        Thank you!

    div id="footer"
      == render 'footer'

That’s it! Now, just use the .slim extension and you’re good to go.

Verbatim Text

The pipe | tells Slim to just copy the line. It essentially escapes any processing. Each following line that is indented greater than the pipe is copied over.

1
2
3
4
body
  p
    |
      This is a test of the text block.

If the text starts on the same line, the left margin is set at the indent of the pipe (|) + one space(). Any additional spaces will be copied over.

1
2
3
4
5
6
body
  p
    | This line is on the left margin.
       This line will have one space in front of it.
         This line will have two spaces in front of it.
           And so on...

Control code

The dash ‘-’ denotes control code. Examples of control code are loops and conditionals. end is forbidden behind -. Blocks are defined only by indentation. If your ruby code needs to use multiple lines, append a backslash \ at the end of the lines. If your line ends with comma , (e.g because of a method call) you don’t need the additional backslash before the linebreak.

1
2
3
body
  - if articles.empty?
    | No inventory

Output =

The equals sign tells Slim it’s a Ruby call that produces output to add to the buffer. If your ruby code needs to use multiple lines, append a backslash \ at the end of the lines. For example:

1
2
3
= javascript_include_tag \
   "jquery",
   "application"

If your line ends with comma , (e.g because of a method call) you don’t need the additional backslash before the linebreak. For trailing or leading whitespace the modifiers > and < are supported.

  • Output with trailing white space =>. Same as the single equals sign (=), except that it adds a trailing white space.
  • Output with leading white space =<. Same as the single equals sign (=), except that it adds a leading white space.

Output without HTML escaping ==

Same as the single equals sign (=), but does not go through the escape_html method. For trailing or leading whitespace the modifiers > and < are supported.

  • Output without HTML escaping and trailing white space ==>. Same as the double equals sign (==), except that it adds a trailing white space.
  • Output without HTML escaping and leading white space ==<. Same as the double equals sign (==), except that it adds a leading white space.

Closed tags (trailing /)

You can close tags explicitly by appending a trailing /.

1
img src="image.png"/

Note, that this is usually not necessary since the standard html tags (img, br, …) are closed automatically.

Inline tags

Sometimes you may want to be a little more compact and inline the tags.

1
2
3
ul
  li.first: a href="/a" A link
  li: a href="/b" B link

For readability, don’t forget you can wrap the attributes.

1
2
3
ul
  li.first: a[href="/a"] A link
  li: a[href="/b"] B link

Dynamic content (= and ==)

Can make the call on the same line

1
2
body
  h1 id="headline" = page_headline

Or nest it.

1
2
3
body
  h1 id="headline"
    = page_headline

Ruby attributes

Write the ruby code directly after the =. If the code contains spaces you have to wrap the code into parentheses (…). You can also directly write hashes {…} and arrays […].

1
2
3
4
5
6
body
  table
    - for user in users
      td id="user_#{user.id}" class=user.role
        a href=user_action(user, :edit) Edit #{user.name}
        a href=(path_to_user user) = user.name

The attribute value will be escaped by default. Use == if you want to disable escaping in the attribute.

1
a href==action_path(:start)