An Introduction to Slim Templates

Why Slim?

If you live and breathe in Ruby land and have given Haml a shot before, you’ll probably already know a couple of the arguments I’m going to make. I think it’s nevertheless a good idea to follow along because you might have already decided to use a more minimalistic templating engine and I’d like you to see the advantages Slim offers as well.

Before we dive into why Slim is cool, I want to cover what Slim actually is and what it does for you. The documentation sums this up quite nicely:

“Slim is a fast, lightweight templating engine with support for Rails 3 and 4”.

You can also use it with Sinatra and even plain Rack. So, if you are a bit tired of using ERB for writing your templates or you are not super satisfied with what Haml has to offer, then Slim is exactly the right tree for barking up.

In regards to its syntax, the people behind Slim were trying to find an answer to the following question: “What’s the minimum required to make this work?” For writing the minimal amount of front-end code possible, this sure sounds like the right question to ask.

Does Slim offer a perfect solution to all your templating concerns? Probably not, but quite frankly, it might just offer the best! Is it easy to learn? I think so, but it’s hard to know what other people consider easy. I’d say this, though: it takes a bit to get used to, but it’s definitely no rocket science. So no need to feel intimidated if you are a bit new to the coding side of things. Will you have a good time with it? Absolutely!

So, why Slim? The answer is quite straightforward, I think. Your markup should be as readable and beautiful as possible! You should have a good time working with it, and the less time you need to spend wading through tons of tag matter the better.

What is beautiful, you might ask? Of course, that is not an answer I’ll try to tackle, but being minimal in that regard rarely hurts. What about becoming super cryptic because the templating engine tries to be super smart in being minimal? That is a fair concern, and you’ll be happy to hear that the team behind Slim takes this very seriously. They want to remove as much as possible from plain old HTML and reveal only the essential parts—all without becoming too cryptic. Their core team tries to go even a step beyond that, and they are really concerned about the aesthetics of Slim code. Pretty good deal, don’t you think?

Isn’t it much nicer if you can just glance at a template and be able to easily digest what’s going on? Templates can become a very ‘crowded’ place—even if you make intelligent use of partials—and as a consequence, you want to reduce the amount of noise to the absolute minimum.

Have you maybe tried the indented Sass (.sass) syntax? I hope you have, because it’s just plain dope! If so, you probably will have a similar appreciation for what Slim has to offer. It’s also whitespace sensitive, which leads to really succinct and readable code. Let’s take this piece of HTML/ERB code and compare it to Slim.

<!DOCTYPE html> <html>   <head>     <title><%= full_title(yield(:title)) %></title>     <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>     <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>     <%= csrf_meta_tags %>   </head>   <body>     <header class="navbar">       <div class="logo">         <%= link_to "sample app", 'root_path', id: "logo" %>         <nav>           <ul class="navbar-right">             <li><%= link_to "Home",   'root_path' %></li>             <li><%= link_to "Help",   'help_path' %></li>             <li><%= link_to "Log in", 'login_path' %></li>           </ul>         </nav>       </div>     </header>     <div class="main">       <%= yield %>     </div>   </body> </html>

Let’s look at the Slim equivalent:

doctype html html   head     title = full_title(yield(:title))     = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true     = javascript_include_tag 'application', 'data-turbolinks-track' => true     = csrf_meta_tags   body     header.navbar       .logo         = link_to "sample app", 'root_path', id: "logo"         nav           ul.navbar-right             li               = link_to "Home",   'root_path'             li               = link_to "Help",   'help_path'             li               = link_to "Log in", 'login_path'     .main       = yield

The first thing people often recognize is, “Hey, no closing tags!” Cool? Sure, you are not used to the syntax yet so it might look a bit alien at first, but I’m sure you can appreciate how succinctly it reads. No left/right angle brackets, and no need to write divs and minimalistic selectors, so instead we can focus on the name the ids and classes have. It feels a lot less messy and more organized, don’t you think?

For comparison, here is the Haml version. It’s really not meant as an opportunity to bash Haml—it just shows you how similar it is, but also that Slim goes a step further with its choice of minimal syntax. The result is that it’s even more elegant than Haml, I think.

Why go so minimal but still make me type the % sign all over the place? My index finger has no special motivation to grab Shift-5 all the time. Can you customize that behaviour? Pretty sure, or at least I hope so! But the design seems a bit flawed in that regard and less spartan compared to Slim. I realize that this is also a matter of taste, though, so I’ll leave it at that.


!!! %html   %head     %title= full_title(yield(:title))     = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true     = javascript_include_tag 'application', 'data-turbolinks-track' => true     = csrf_meta_tags   %body     %header.navbar       .logo         = link_to "sample app", 'root_path', id: "logo"         %nav           %ul.navbar-right             %li= link_to "Home",   'root_path'             %li= link_to "Help",   'help_path'             %li= link_to "Log in", 'login_path'     .main       = yield

Before we jump into the meaty parts, let me be puffy for a moment and sum up what I think makes learning Slim a worthy investment of your time:

  • It’s speedy.
  • Super readable.
  • It has a smart syntax.
  • Its aesthetic is minimal.
  • It is highly configurable
  • It’s index-finger friendly.
  • It’s boss-level templating.
  • It’s fun to write and looks dope.
  • Automatic HTML escaping by default.
  • Super nice Rails and Sinatra integration.
  • Very minimal templates that are easy to maintain.
  • It’s extensive and allows you to write plugins and extensions.
  • There is a logicless mode for times when you want to output HTML but have no reason to include Ruby code.
  • It has configurable shortcuts for tags—which is a pretty nice feature to customize the engine to your needs.
  • And finally, because Slim’s syntax is guided by one very cool motto: “What’s the minimum required to make this work”. This is very hard not to like.

What Are Templates?

In terms of programming experience, if you consider yourself to be more on the newbie side of things, I’ll try to give you a quick round trip before we start using Slim. When people talk about templates, they mostly mean plain HTML markup with dynamic code that is often used for flow control, object injection or partial template (partials) rendering. For example, when a controller provides you with instance variables that can be used by the view via (instance) variable substitution to display attributes from that object. All this happens via the template processor of your choice—ERB, Haml, Slim and the like—which combines all your web templates into a final web page. Templates can also be used to generate XML and RSS feeds as well as other forms of structured text files.

With templates, you can define various “layouts” that are handling particular parts of your website as well as the data that needs to be displayed systematically with the smallest amount of repetition. Since you started playing with Rails, you surely have been using ERB for exactly these kinds of scenarios. ERB takes the plain text portions, hands them to the final document and only processes code that is marked as such. I’m not going into details how ERB works and suppose you have a basic understanding before you dive into Slim. I would not recommend using Slim if you are not already familiar with Rails’ default way of templating since you will have a much easier time playing with Slim if you understand how this works out of the box in Rails.

Below is a basic ERB example of a template that displays a collection of missions that are associated with an @agent object. Directly below, it also uses a method from a Ruby Gem to paginate the @missions collection.

<% if @agent.missions.any? %>   <h4>Missions (<%= @agent.missions.count %>)</h4>   <ul class="missions">     <%= render @missions %>   </ul>   <%= will_paginate @missions %> <% end %>

This is a small section of a template that shows nicely that it’s nothing more than a static HTML part that has some dynamic injections from some Ruby code. If we didn’t use templates like this, we’d have to manually write code for every new object that we want to see displayed on a page. Not sure about you, but I can’t imagine a bigger nightmare or waste of time than that. Templates give us a handy tool for making our view layer smart and dynamic without repeating ourselves.

As you can also see from this example, templates let us use partial templates that we can render where needed. Here we would have a _mission.html.erb partial somewhere, which helps us to iterate over a collection of @mission objects, which in turn get listed inside our missions class.

As you can see, templates are nothing magic but are super handy to make developing web apps a lot more efficient and organized. I just wanted to make sure that we are all on the same page with this before diving into Slim.

What About ERB & Haml?

If you like using these tools, it’s perfectly fine. Nothing wrong with that. The thing is, if you are looking for something smarter that is more minimalistic, it’s hard to find something that goes further than Slim. To me, it’s the most streamlined templating solution in Ruby land that I know of. They all work fine, so it’s a matter of personal preference.

Getting Started

Slim With Rails

No surprise, there is a gem for that.


gem 'slim-rails'


bundle install

That’s it, we’re all set. Because you installed this gem, Slim will get loaded and initialized whenever your app loads. Also, for your convenience, when you generate controllers via rails generate controller , you will automatically get .slim view files for your view— .html.erb files no more. It works the same with scaffolds, but I hope you are not using them really!

To demonstrate this behaviour for folks who are new to using Rails generators, I’ll create a controller for secret service operatives that has all the standard REST controller actions:


rails generate controller SecretServiceOperatives index new create show edit update destroy

Among other stuff, you’ll get all the .slim files you need. Rails puts an extra .html in there as well—you can get rid of that if it bothers you, of course. All that matters is that the slim file extension is already there and that it’s ready for preprocessing your Slim code. Yay!

...  invoke  slim      create    app/views/secret_service_operatives      create    app/views/secret_service_operatives/index.html.slim      create    app/views/secret_service_operatives/new.html.slim      create    app/views/secret_service_operatives/create.html.slim      create    app/views/secret_service_operatives/show.html.slim      create    app/views/secret_service_operatives/edit.html.slim      create    app/views/secret_service_operatives/update.html.slim      create    app/views/secret_service_operatives/destroy.html.slim  ...

The next step would be to open your application layout and to replace the boilerplate code with something Slim. Also, don’t forget to rename the application.html.erb file to application.slim (or application.html.slim if you want). We have already slimmed down a bit—even the file name has lost some weight.


doctype html html   head     title     = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true     = javascript_include_tag 'application', 'data-turbolinks-track' => true     = csrf_meta_tags   body     header.navbar       .logo         = link_to "Spy app", 'root_path', id: "logo"         nav           ul.navbar-right             li               = link_to "Home",    'root_path'             li               = link_to "Help",    'help_path'             li               = link_to "Sign up", 'sign_up_path'             li               = link_to "Log in",  'login_path'     .main       h1.welcome Welcome to Boss Level Slim Templates!       = yield

Nothing fancy, but a good start—and as easy as can be I think.


An Introduction to Slim Templates

As a side note, if you are ever curious which version of the gem you have installed, this little command will tell you—it’s handy for any gem as well, of course:


bundle show 'slim-rails'

It tells you where it is stored and which version this gem currently has. The output looks like this:


Slim With Sinatra

For the Sinatra enthusiasts among you, I wanted to mention how to get started as well. First we need to install the gem, of course.


gem install slim

And after that, you are almost done. In your Sinatra app, you just need to require Slim and you are good to go.


require 'sinatra' require 'slim'  get('/') { slim :index }  __END__  @@ index doctype html html   head     title Slim Templates     body       h1 Boss Level Ruby Templates With Slim

Here I used an inline template to write the Slim markup in the same file and told Sinatra that I want to use Slim for the index file when it makes a get request to the root path. I just needed to reference the inline template inside a curly braces block. What you see below the @@ index —which signifies the index template—is all whitespace sensitive Slim syntax.


An Introduction to Slim Templates

Time to show you how to write some Slim.



HTML <!DOCTYPE> Declaration

Let’s start with the simplest one, the doctype declaration. As you probably know and already forgot, this must be declared on top of your HTML document—before the actual <html> tag. FYI, it’s not an HTML tag and instructs the browser about the version of the HTML page. 

Among the different versions for <!DOCTYPE> , there is only one for HTML5: <!DOCTYPE html> —thank god!—which is exactly what we get when we write doctype html or doctype 5 in Slim.

doctype html html   head  doctype 5 html   head

ID Shortcut # and Class Shortcut .

Writing front-end code means a ton of classes and ever so few ids—I hope. To avoid writing these over and over again, Slim meets you more than halfway and lets you short-circuit the whole process basically. Let me show you what I mean. Take the following Slim code:

#logo h1.header .evil-wrapper   h2#author-name   ul.books

This gets compiled to this HTML output:

<div id="logo"></div> <h1 class="header"></h1> <div class="evil-wrapper">   <h2 id="author-name"></h2>   <ul class="books"></ul> </div>

As you can see, the dot suggests to Slim that you want to use a class, and the name that follows is what you want to name it. The same goes for ids—you just use the hash symbol (aka pound sign) which does the trick. Astute readers surely recognized that the versions without a leading tag trigger the creation of a div with the corresponding class or id—which can be seen for <div id="logo"></div> and <div class="evil-wrapper"></div> . Pretty handy, don’t you think?

You can also be more expressive in your Slim code if you want to. Nobody hinders you from writing your good ol’ classes and ids by hand. If you somehow feel attached to that, go for it! I like the more succinct version because it also lets me avoid typing quotes and repeated text all the time. It’s up to you—whatever makes you happy! The code below is a bit more verbose but renders the same HTML as above:


div id='logo' h1 class='header' div class='evil-wrapper'   h2 id='author-name'   ul class='books'

Now, isn’t that a thing of beauty? Imagine all these dreaded HTML tags that you don’t need to write yourself, plus getting rid of all the excess enclosing angle brackets. Sure, your code editor can do a lot of this work for you as well, but does your editor also read the code for you? Exactly!

When you come back to read your code, you also want a succinct document that is super easy to digest visually. I think this simple example shows best what a tool like Slim has to offer. It’s these little things that add up to a great tool and timesaver in the long run. Even if you only use it for exactly that functionality and ignore the other more advanced features for now, making the switch to Slim would already pay off big time.

Inline Tags

Let’s say you have multiple tags that you want to have inline for being more compact or whatever. So instead of breaking to a new line, you can chain them by separating these tags with a colon : . Both examples below render the same output.


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

HTML Output:

<ul>   <li class="link">     <a href="/a">A link</a>   </li>   <li>     <a href="/b">B link</a>   </li> </ul>

The second version is more minimal because of the inlined tags and would be my preference. After all, compact is good, no? I think this case shows nicely that Slim evenly balances between compact and cryptic. Yes, it takes a bit of getting used to, and in some cases additional attribute wrappers are helpful (see more about wrappers below). Call me crazy, but I’m pretty certain that you’ll read Slim like regular HTML markup in a jiffy.

Text Content

Writing text is as easy as you’d expect, of course. Just add it on after your tags.


h1#welcome-header Your funky welcome message goes here!

HTML Output:

<h1 id="welcome-header">   Your funky welcome message goes here! </h1>

Nothing more to add, easy as can be!


HTML attributes, which provide additional info about the tags, can be included as follows:


a href="http://slim-lang.com" title='Slim Homepage' Goto the Slim homepage  img alt="James Bond posing together with M" src="image.png" height="90" width="90"/

HTML Output:

http://slim-lang.com" title="Slim Homepage">Goto the Slim homepage  <img alt="James Bond posing together with M" height="90" src="image.png" width="90" />

You can basically chain them on and Slim will separate it from the text content—if present. If you look closely, you can see that our img tag has a trailing slash, which explicitly closes tags in Slim. For images or more convoluted tags, this is surely useful. By the way, HTML5 does not require you to write the attribute names in lower case nor to use quotes around attribute values. It is nevertheless recommended standard practice by the W3C.

Attribute Merging

If you have multiple selectors like classes or ids per tag, you can also write this more succinctly by daisy-chaining them. These selectors will be automatically delimited by whitespace.


h2#big-header.agent-header.tagline Funky headline  h3.small-header.agent#007.tagline Small funky headline

HTML Output:

<h2 class="agent-header tagline" id="big-header">   Funky headline </h2> <h3 class="small-header agent tagline" id="007">   Small funky headline </h3>

Not that having all these ids and classes mixed up like this represents best practices or anything, but it’s easy to see how Slim works in such a convoluted example. Pretty cool, huh? Careful, though—spreading these selectors across multiple lines won’t work without attribute wrappers (see next section).

Another option would be to use an array with strings or just symbols to merge in attributes.


h2 class=["agent-header","tagline"] Funky headline  h3 class=:agent,:double_o_seven,:tagline Small funky headline

HTML Output:

<h2 class="agent-header tagline">   Funky headline </h2>  <h3 class="agent double_o_seven tagline">   Small funky headline </h3>

In my book, I’d call this one a good-to-know, but it’s not something I try to actively use. It might be handy if you want to interpolate something, I suppose.

Attribute Wrappers

Slim offers you wrappers to make your attributes easier to read. It might not be necessary all the time, but it’s handy to know if a tag with lots of attributes needs some taming. You can use any of the following delimiters to wrap attributes: {} , [] and () .


a{href="http://slim-lang.com" title='Home page'} Goto the home page  a{href="http://slim-lang.com/about.html" title='About page'   class='link' id='about'} Goto the about page  h2[id="big-header" class="agent-header tagline"] Funky headline  h3(id="small-header"    class="agent 007 tagline") Some other funky headline

HTML Output:

<a href="http://slim-lang.com" title="Home page">Goto the home page</a>  <a class="link" href="http://slim-lang.com/about.html" id="about" title="About page">Goto the about page</a>  <h2 class="agent-header tagline" id="big-header">   Funky headline </h2>  <h3 class="agent 007 tagline" id="small-header">   Some other funky headline </h3>

If that’s an easier way for you to organize the markup, go for it! As illustrated by the second a and the h3 tags, you can even spread attributes and selectors across multiple lines. Indentation seems to be enforced very forgivingly in regards to whitespace sensitivity. My guess, though, is that it won’t be for long, and you won’t need wrappers much. You‘ll get used to the barebones Slim syntax in no time and save them for special occasions—as you probably should.

For inlined tags, wrappers might come in handy every once in a while. As you can also observe in the example below, you can use spaces with the delimiters to make it even more readable—just a side note.

ul   li.long-link: a{ href="http://slim-lang.com" title='Home page' } Goto the home page   li.long-link.class.with-id: a[ href="http://slim-lang.com/about.html" title='About page'                                  class='link' id='about' ] Goto the about page    li.c-link: a(href="/c") C link   li: a[href="/d"] D link

HTML Output:

<ul>   <li class="long-link">     http://slim-lang.com" title="Home page">Goto the home page   </li>   <li class="long-link class with-id">     http://slim-lang.com/about.html" id="about" title="About page">Goto the about page   </li>   <li class="c-link">     <a href="/c">C link</a>   </li>   <li>     <a href="/d">D link</a>   </li> </ul>

Attribute Interpolation

Did somebody say interpolation? Within quoted attributes, you can use Ruby to interpolate code if needed. A simple example should be enough to illustrate this behaviour:


a href="http://#{url}" Goto #{url}

Again, not something you might use on a daily basis, but it sure is good to have in your bag of tricks. The attribute values will be escaped by default. If you need that behaviour disabled, just use a == .

a href=="http://#{url}" Goto #{url}

You can use full-on Ruby to play with your attributes as well. Just throw an equals sign in there where you want some Ruby code to be executed, and you are ready to go. In the second article, you’ll find more information about outputting Ruby code in your Slim templates.

ul   li id="agent_#{agent.id}" class=agent.role     a href=(path_to_agent agent) =agent.name

That, of course, also means that you can use simple booleans the same way in your attributes as well.

input type="text" disabled=false input type="text" disabled=true input type="text" disabled=nil

Groovy, let’s move on!

Final Thoughts

I hope you now have a good sense of why Slim is a good choice for all your templating needs in Ruby land. If you still prefer to use Haml or ERB at the moment, you might grow an appetite for Slim over time. I’m not saying it’s an acquired taste or anything, just that it’s not something that many people pick up early in their careers—maybe because they haven’t yet felt the pain of writing all that excess markup over and over again. This article should provide you with the basics that you need to get started.

Slim has more to offer, of course—especially a few advanced features that you definitely want to take a look at. In the next article, we’ll start with a more detailed section about outputting Ruby code into your templates—and much more, of course. See you there!

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » An Introduction to Slim Templates

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址