DEV Community

Cover image for Strict locals in Slim / Haml partials in Rails
Matouš Borák for NejŘemeslníci

Posted on

Strict locals in Slim / Haml partials in Rails

When I saw the announcement about partial template strict locals in Rails 7.1, I was excited but it took me a long time to realize that this is not an ERB-only feature but that it should actually work in any template language, including my favorite – Slim! I even remember trying it back then but failing, probably due to an incorrect syntax. While there are many nice tutorials explaining template strict locals out there, they are all ERB-centric so let’s take a look how this feature can be used in Slim or Haml templates, respectively.

Preparations

Suppose we want to render a partial template from a main one one, to show an important message:

/ main.html.slim

= render "notice"
Enter fullscreen mode Exit fullscreen mode
/ _notice.html.slim

h1
  ' Note:
  = message
Enter fullscreen mode Exit fullscreen mode

If we run this code, it will fail with an ugly and misleading error message:

undefined local variable or method message for an instance of #<...>
Hint: message is probably misspelled.

saying that we probably misspelled message which we did not - we forgot to pass the local variable in the first place.

Adding a magic comment

Let’s make the partial template recognize our local variable using a strict locals magic comment:

/ _notice.html.slim

/# locals: (message:)

h1
  ' Note:
  = message
Enter fullscreen mode Exit fullscreen mode

Note that the exact syntax is important here: it must be a comment (denoted by the slash / character in Slim), then a hash (#), a space, then locals:, another space and finally something that resembles a method arguments definition with keyword arguments specifying the needed local variables. The reason this syntax is so strict is that it gets matched by a regular expression deep in the Action View templates processing code.

In case of a HAML template, the syntax differs only by the magic comment leading character, it must be -# instead of /:

/ _notice.html.haml

-# locals: (message:)

%h1 Note!
  = message
Enter fullscreen mode Exit fullscreen mode

Note that both magic comments are code comments, i.e. they are not output to the final HTML.

Once we have this magic comment in place, we get a much better error:

missing local: :message

and the stack trace leads us to the proper place (to the line with render in the main template) right away.

And of course, all other strict locals goodies work, too, such as the default values or prohibiting any locals.

Closing thoughts

Up till now, we commonly used the local_assigns hash to notify the reader that our variable is to be passed from the outside and to set its default value. We think that strict locals make this hash a little obsolete as they serve very similar purposes with a nicer syntax.

Although we still prefer View Components for our most sophisticated view template blocks, we will definitely use Rails partials with more pleasure since we can be sure now to write them in a safer way. 👍🏻

Top comments (0)