Building Simple Web Apps with Ruby, Part 5

In this post I want to switch around some of what we already did regarding HTML and CSS, by using “variants” of these. Specifically, I’ll look at Slim (to replace our HTML/ERB) and Sass (to replace our CSS).

The easiest change to make is to that of our HTML. So let’s say we no longer want to use ERB. We want to use Slim. Slim is a template engine just like ERB is. The idea behind Slim is that you can trim down the amount of writing you do with HTML or ERB. There is, in fact, another templating engine out there called HAML that some people recommend over Slim. Really, the choice is up to you. In fact, there are more than just these two variants. What I’ll show you how to do here is experiment with at least one of them. Then you can use these same techniques to incorporate other engines.

I also want to consider using Sass (Syntactically Awesome Stylesheets). This is a CSS templating engine, which means that you write your styles in Sass which then get compiled on the server side into the CSS that is sent to the browser.

Getting Slim and Sassy

Okay, so how do we convert our ERB approach to a Slim approach and our CSS approach to Sass?

Since Slim and Sass are both gems, you need to require this at the top of your app.rb script:

Because we are adding gems, you do have to go through the modify-Gemfile-bundle-update procedure. So let’s update Gemfile:

Make sure to do this:

bundle update

Slimming Your Markup

We’ll start off with Slim because that’s a bit easier. The easiest way to convert to a Slim approach is to change all your routes such that instead of this line:

you have this instead

What that’s going to do is tell Sinatra that you want to use Slim to template your files. Because of this, you need to change the extension of your files in the views directory from “*.erb” to “*.slim”. Remember that since you’re using Git, you’ll want to do this:

git mv views/*.erb views/*.slim

That will make sure Git knows an existing file has been changed rather than a new file being added.

Make sure you do the above two actions: (1) change all erb lines in your app.rb file to slim and then (2) make sure all of your erb files in the views directory now have the extension “.slim”.

With just that done, if you try to visit any of your pages, you will get an error that talks about “malformed indentation”. This is an important thing to understand: Slim (like HAML) is indentation based. This is similar to how Python works. Some people utterly hate this and others just dislike it severely. Personally I’ve always been okay with indentation approaches since it helps enforce a nested structure.

So to fix the error you now have to convert your HTML/ERB format to Slim. As you might imagine, just changing a file extension is not enough. The good news is that there are apps out there to help you do this, such as Html2Slim. That being said: be careful of converters. As you can imagine, they don’t always quite get everything right.

This isn’t really the place to go into a tutorial of Slim, so I’ll settle for showing you what each of my files look like after conversion:


Note: It’s quite possible that some converters will change your yield line “= yield” rather than “== yield”. If that’s the case, make the change as you see it above or your layout will not work.


Check it at: http://localhost:9292/.


Check it at: http://localhost:9292/adhoc.


Check it at: http://localhost:9292/stardate.

Congratulations — you’ve just slimmed down your HTML. Again, I’m not really going to go into a tutorial of Slim at this point. There are plenty of resources out there that can do a better job than I can. Just note that the indentation does matter. Further, you can see that some of the boilerplate type markup has been removed. Beyond the basics, I just wanted you to see how to use an alternative templating engine for HTML beyond ERB. The same steps you followed here would largely apply to any templating engine you decide to use, like HAML, for example.

There is one other thing I’d like to show you. Each templating engine has its own way of displaying the markup. If you view the page source for any of the pages you just “slimmed” you will see it is very hard to read. That may not matter to you and it certainly does not impact how the markup is displayed. But if you want the source to look a little nicer, you can add the following to your app.rb script:

This is a slim-specific configuration that lets you have the page markup formatted a litter nicer in terms of readability. I bring this up because each templating engine will have its own configurations and the above place in your app.rb script is where you would set those configurations.

Sassing Your Styles

Now let’s talk about Sass. This can get confusing because you will hear about SCSS (Sassy CSS) and Sass (Syntatically Awesome StyleSheets). There’s lots of sites out there that explain the difference but basically Sass eventually introduced SCSS as the syntax of Sass. Think of Sass as an engine that can compile SCSS and have that become the CSS that browsers will recognize.

If you want a little history, Sass was originally designed to handle some of the issues people felt existed with CSS, such as, for example, the lack of ability to specify variables that could be used in more than one CSS rule. So Sass was basically an attempt to make a better CSS. The idea was that Sass was a type of compiler — or more accurately a preprocessor — that would translate this new syntax into CSS syntax. Why go to all this trouble just to end up with the same thing? Because the CSS you write with Sass could use some new features that would make everything less complicated to write in the first place and maintain later.

While a lot of people liked the idea behind Sass, it was felt that the design was too complicated for web designers who were used to the relatively more simple, straight-forward CSS syntax. So eventually SCSS (Sassy CSS) was introduced as part of Sass. SCSS is a superset of CSS, which means any valid CSS will work as valid SCSS. (Similar to how valid HTML worked just fine as valid ERB.) However, SCSS is a scripting language and thus it does have expressions, functions, the ability to use conditional logic, and so on. You don’t have to use those things, but you can.

First, add the following handler to app.rb:

This basically picks up the reference to css/style.css that you already have in your layout file and loads the Sass file called style.scss. Make sure that’s clear: the get request is for “css/style.css” because that’s what is referenced in the head section of your layout.slim file. You will never reference a “style.scss” because a browser (currently anyway) won’t know what to do with a .scss file. So what Sinatra does here is follow the route but then overrides what happens.

This is great but we don’t have a style.scss file yet. Now, a problem rears its head here and it’s not necesarily an obvious one: going the path I am showing you here, this scss file needs to be saved in the views directory. So let’s do this: copy your style.css to your views directory and name it style.scss:

cp public\css\style.css views\style.scss

So now the contents of style.css (in the public folder) matches the contents of the style.scss (in the views folder). But which one is being used? Well, let’s make this change in the style.scss file (in the views directory):

If you go to http://localhost:9292/adhoc and submit the form, the border and text alignment should show up for the flash message. That means the scss file is being correctly read since that change is not in your css file. In fact, you could actually delete the style.css at this point if you wanted to.

If you take a look at how the app now looks in the browser, nothing should have changed. This is because SCSS is a superset of CSS, so any regular CSS will just work as expected. So all we have just done is moved from using standard CSS to SCSS. But what if you wanted to use some of the SCSS specific stuff? Well, here’s my original style.css:

Let’s convert that to SCSS. As with going from HTML to Slim, there are converters out there that attempt to help you, such as css2sass. And, as with the previous caveat, note that converters can sometimes lead you down a bad path. Notice with this tool that there are two buttons: convert to SASS and convert to SCSS. For now, I’m using just SCSS. So here is my css converted to scss:

Not a whole lot of difference, right? One thing you might notice there is ability to nest your declarations. See how the “header h1” became an “h1” nested underneath “header”. At first I didn’t care about this feature at all, but I’ve come to really appreciate it. I also mentioned that SCSS is a scripting language. One of the things you can do with it is create a variable. At the top of the style.scss file, add this:

Now change the notice rule declaration to this:

I’m just scratching the surface here so that you can see there are, in fact, differences.

If you check your file system now, you will see that there is a .sass-cache directory in your root project directory. The reason this exists is that Sass is a compilation system. Since Sass does compiling, very large files or very complex files could add time to rendering the page with the styles. So the cache is a way to store compiled elements for re-use so that performance is quicker.

All that said, you definitely don’t want to track this as part of Git, so add a .gitignore file to your root project directory and put the following in it:


One thing you should do at this point is redploy to Heroku and make sure everything still works. Remember that you can use foreman to try out the execution environment before you do so. The reason I say this is a good thing to try is because you’ve done a lot here. You’ve used two new gems (Slim and Sass) as part of your operating context and you’ve changed how your markup is generated as well as how your stylesheets are generated.

In the next post I’ll explore a little more about using Sass directly (rather than just SCSS) and I’ll also look at the possibility of using another alternative, this time to JavaScript.

About Jeff Nyman

Anything I put here is an approximation of the truth. You're getting a particular view of myself ... and it's the view I'm choosing to present to you. If you've never met me before in person, please realize I'm not the same in person as I am in writing. That's because I can only put part of myself down into words. If you have met me before in person then I'd ask you to consider that the view you've formed that way and the view you come to by reading what I say here may, in fact, both be true. I'd advise that you not automatically discard either viewpoint when they conflict or accept either as truth when they agree.
This entry was posted in Sinatra, Web Development. Bookmark the permalink.

3 Responses to Building Simple Web Apps with Ruby, Part 5

  1. phil kirkham says:

    Lesson 5 completed and deployed – thanks !

    Not sure I like the indentation stuff, more practice required…

    • Jeff Nyman says:

      Yeah, anything that is indentation based can be either a bit of a challenge or a bit of a pain. When I was learning Python I had to adopt the indentation approach and initially I found it a bit off-putting. I grew to accept it but I can’t say I prefer it.

      In terms of languages like Slim and HAML, I find I can accept it a bit better because what it’s giving me is the ability to minimize what I have to type. I also like that it does force a consistent structure — as it does with Python — but a downside to that is it’s very easy to make what amounts to a “whitespace error”. And whitespace has never seemed like something that should cause me errors!

      I’ll be the first to admit, the jury is still out for me on this.

  2. Nice article!

    In case you didn’t know, you can also useĀ <pre><code>doctype html</code></pre> and other such declarations Slim supports to create the HTML Doctype tag. I think it’s prettier that way personally.

    Anyhow, I dig your zen outlook on life especially. Thanks for the great tutorials on modern tools!

Leave a Reply

Your email address will not be published. Required fields are marked *