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"
/ _notice.html.slim
h1
' Note:
= message
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
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
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)