Slim: A HTML Templating Language
Tags: webdev, html, slim, tutorial
Published: 2023-01-09 10:00:00

In this part of the series, let's explore another popular templating language, [Slim](https://github.com/slim-template/slim).

It is developed in the Ruby language and is often used to create view templates for Ruby on Rails projects. But apart from that, it is very similar to [Pug](https://pugjs.org/api/getting-started.html) as well as other templating languages. 


## Table of Contents

- [A Basic Example](#a-basic-example)
- [Start a Slim Project](#start-a-slim-project)
  * [Compile From Command Line](#compile-from-command-line)
  * [Use Slim in Ruby Frameworks](#use-slim-in-ruby-frameworks)
- [A More Advanced Example](#a-more-advanced-example)
- [Conclusion](#conclusion)

---

## A Basic Example

Here's an example of a simple Slim template that generates an HTML page with a heading and a paragraph:

```slim
doctype html
html
  head
    title My Site
  body
    h1 Hello, World!
    p This is my site.
```

You may have noticed that it looks _EXACTLY_ the same as the basic example of Pug we saw in [part 1](https://dev.to/jessewei/pug-a-html-templating-language-3oe2) of the series. If you understand another templating language like Pug, you'll be comfortable using Slim too.

And it would be _compiled_ into the exactly same HTML:

```html
<!DOCTYPE html>
<html>
  <head>
    <title>My Site</title>
  </head>
  <body>
    <h1>Hello, World!</h1>
    <p>This is my site.</p>
  </body>
</html>
```

The rendered page from the HTML looks like this:


![Rendered page from basic example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4kx3e9wk3xstl5q5b0of.png)


<figcaption>Rendered page from basic example</figcaption>

Also as we discussed in [part 1](https://dev.to/jessewei/pug-a-html-templating-language-3oe2) of the series, templates writen in languages other than HTML must be _compiled_ into HTML files before being served to the browser for rendering and this applies to Slim as well.


![How Slim works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rwlihfizvhiaia1m9vv5.png)

<figcaption>How Slim works</figcaption>

---

## Start a Slim Project

There are many different ways to start a Slim project depending on how you want to use it.

### Compile From Command Line

The easiest way to start is to install the `slimrb` command-line tool and use it to compile your Slim files into HTML files.

To install `slimrb`, we use `gem install`:

```bash
gem install slim
```

If you have not yet had `gem` installed on your computer, you may need to install `ruby` first. If you need help, check out [Ruby docs](https://www.ruby-lang.org/en/documentation/installation/).

Then, we can create a Slim file at a location of your choice:

```bash
touch index.slim
```

Add some code to the new file. I'll use code from our basic example here:

```slim
doctype html
html
  head
    title My Site
  body
    h1 Hello, World!
    p This is my site.
```

Finally, compile the file to HTML file from command line:

```bash
slimrb index.slim -p > index.html
```

The `-p` option tells `slimrb` to output a _pretty_ (formatted) index.html file.

### Use Slim in Ruby Frameworks

Most often, we want to use Slim in Ruby Frameworks such as Rails. In such cases, we can just write view templates in Slim (often with the help of a Slim template generator) instead of HTML and the built-in renderer of the framework will do the rest for us. 

Slim can be also used in projects of other languages such as Javascript with the help of proper packages. 

---


## A More Advanced Example  

This example demonstrates how to use variables, how to loop over a list, conditional rendering and css styling in Slim templates:

```slim
- heading = "My Shop"
- items = [{name: 'Calculator', price: 10, available: true}, {name: 'Note Pad', price: 2.5, available: false}, {name: 'Pen', price: 6, available: true}]

doctype html
html
  head
    title My Shop
  body
    h1= heading
    table
      thead
        tr
          th Item Name
          th Item Price
          th Availability
      tbody
        - items.each do |item|
          tr
            td= item[:name]
            td= item[:price]
            - if item[:available]
              td In Stock
            - else
              td.alert Out of Stock

css:
  table, th, td {
    border: 1px solid grey;
    border-collapse: collapse;
  }
  th, td {
    padding: 10px;
  }
  .alert {
    color: red;
  }
```

This template is compiled to the following HTML file:

```html
<!DOCTYPE html>
<html>
  <head>
    <title>My Shop</title>
  </head>
  <body>
    <h1>
      My Shop
    </h1>
    <table>
      <thead>
        <tr>
          <th>
            Item Name
          </th>
          <th>
            Item Price
          </th>
          <th>
            Availability
          </th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            Calculator
          </td>
          <td>
            10
          </td>
          <td>
            In Stock
          </td>
        </tr>
        <tr>
          <td>
            Note Pad
          </td>
          <td>
            2.5
          </td>
          <td class="alert">
            Out of Stock
          </td>
        </tr>
        <tr>
          <td>
            Pen
          </td>
          <td>
            6
          </td>
          <td>
            In Stock
          </td>
        </tr>
      </tbody>
    </table>
  </body>
</html>
<style type="text/css">
  table, th, td {
    border: 1px solid grey;
    border-collapse: collapse;
  }
  th, td {
    padding: 10px;
  }
  .alert {
    color: red;
  }
</style>
```

And our page should look like this:


![An advanced example of Slim template](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ip033i1nl7471itwv0ie.png)

<figcaption>An advanced example of Slim template</figcaption>

Please note that,

- Spreading variable definition on multiple lines causes syntax error and that's why I kept the `items` definition on a single line (I haven't found a way to spread without an error yet).
- We can also link external stylesheets instead of specifying css rules directly in the template. Suppose we have a `styles.css` in the same directory as our Slim template and we can link the style file like this, which is how we normally do in HTML files:

```slim
...
head
  / we can also use an external stylesheet like this↓
  link href="styles.css" rel='stylesheet' type='text/css'
...
```

Slim can do even more than the advanced example has demonstrated. For example, if you're working on a Rails project, it's likely you would want to create multiple partial templates and include them in other templates. This is when we'd want to use the `= render` method:

```slim
doctype html
html
  head
    title My Shop
  body
    = render 'header'
    div
      p This is my shop
    = render 'footer'
```

Note that the `= render` method is provided by frameworks like Rails but not available if you're using Slim as standalone template engine.

---


## Conclusion

In this part of the series, we learned the basics of Slim, another templating language that is widely used in Ruby frameworks.

It shares a lot similarities with other templating languages like Pug in terms of general concepts and syntax. Thanks to its high expressiveness, it helps speed up development and improve code readability.

And that's it. If you have any questions or feedback on the series, please comment below. Thank you.