Selmer

2 minute read

Selmer

Selmer is a templating framework often used for working with HTML, but it can also be used to transform any kind of text.

Creating templates

Selmer uses the {{var-name}} to declare dynamic variables inside templates. We can provide the actual values for these variables when we render the page using Clojure.

1<html>
2  <head>
3    <meta http-equib="Content-Type" content="text/html; charset=UTF-8"/>
4    <title>Example template</title>
5  </head>
6  <body>
7    <h2>Hello {{name}}</h2>
8  </body>
9</html>

Now we need to render this file and provide a value for name

1(require '[selmer.parser :as selmer])
2
3(selmer/render-file "hello.html" {:name "World"})

We can also iterate over a collection using for:

1<ul>
2  {% for item in items %}
3    <li> {{item}} </li>
4  {% endfor %}
5</ul>

Using filters

Filters allow us to preprocess data before its rendered. They are specified using a pipe symbol |.

1{{name|upper}}

We can also create custom ones using slemer.filters/add-filter!.

Extending Templates

By using extends tag, the current template will use the template it’s extending as the base. Any block tags in the base template with the names matching the current template will be overwritten.

For example we would create a base.html that defines the general structure of our html. We would include a block named content where content of each individual page would go. This approach would look like this:

 1<!-- base.html -->
 2<html>
 3  <head>
 4    <link rel="stylesheet" href="style.css" />
 5    <title>{% block title %}My amazing site{% endblock %}</title>
 6  </head>
 7  <body>
 8    <div id="content">
 9      {% block content %}default content{% endblock %}
10    </div>
11  </body>
12</html>
1<!-- hello.html -->
2{% extends "base.html" %}
3{% block content %}
4  <h2>Hello {{name}}</h2>
5{% endblock %}

Selmer templates are memoized by default meaning that the final version of the template is compiled once and kept in memory. This can be changed with selmer.parser/cache-on! and selmer.parser/cache-off!

Including Templates

include tags allows us to embedd one template in another. For example we want to include a comment form on many templates, we would make comment-form.html to store the html for the form and include it where we need it.

1<!-- register.html -->
2<form action="/comment" method="POST">
3  <label for="name">Name:</lable>
4  <input name="name" type="text">
5  <label for="comment">Comment:</lable>
6  <input name="comment" type="text">
7</form>
1<!-- hello.html -->
2{% extends "base.html" %}
3{% block content %}
4  <h2>Hello {{name}}</h2>
5  {% include "register.html" %}
6{% endblock %}