Introduction
Handling translations in a Rails app is an essential part of creating scalable and maintainable software, especially when supporting multiple languages.
However, as your templates become more complex, repeatedly writing long translation keys can quickly clutter your code. It’s frustrating, harder to read, and of course, prone to mistakes.
Wouldn't it be great if there were a way to simplify this while keeping your templates clean and maintainable? Good news—there is!
Situation
I found myself in exactly this situation. While working on a .html.erb
file, I noticed that a single long locale translation prefix was repeated over and over.
The result? A cluttered, hard-to-read template that felt unnecessarily verbose. I wanted to make it cleaner and more readable.
Solution
Anyway, let's get down to business.
Sample file
Let’s start with a typical .html.erb
file where a long translation key prefix is repeated multiple times.
Here’s a snippet that might look familiar if you’ve worked on Rails apps:
<%# app/views/mailers/sample_mailer.html.erb %>
<table bgcolor="#FFF" align="center" width="600" class="email-body" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td align="left" bgcolor="#FFF">
<h2>
<%= t('mailers.sample_mailer.welcome_email.title') %>
</h2>
</td>
</tr>
<tr>
<td align="left" bgcolor="#FFF">
<p>
<%= t('mailers.sample_mailer.welcome_email.subtitle', user_name: @user.name) %>
</p>
</td>
</tr>
<tr>
<td align="left" bgcolor="#FFF">
<p>
<%= t('mailers.sample_mailer.welcome_email.body', plan_name: @user.plan_name) %>
</p>
</td>
</tr>
<tr>
<td align="left" bgcolor="#FFF">
<small>
<%= t('mailers.sample_mailer.welcome_email.footer') %>
</small>
</td>
</tr>
</tbody>
</table>
In this simple example:
The translation key prefix:
mailers.sample_mailer.welcome_email
is repeated in every call tot
.Code Clutter: The repetitive prefix makes the template unnecessarily verbose.
Error-Prone: If the prefix changes, you’d have to update it everywhere, increasing the risk of mistakes.
This approach works, but as the number of translations increases, it quickly becomes a maintenance nightmare.
The prefix
approach
In order to accomplish this, we're going to use the following as a local variable:
<% prefix = 'mailers.sample_mailer.welcome_email' %>
We assigned the common part of the translation key (mailers.sample_mailer.welcome_email
) to a variable called prefix
.
By defining the common translation key prefix in a variable or directly in the t
helper, you can dramatically clean up your .html.erb
templates.
Make it happen
Here’s the same .html.erb
file after applying the prefix solution:
<% prefix = 'mailers.sample_mailer.welcome_email' %>
<table bgcolor="#FFF" align="center" width="600" class="email-body" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td align="left" bgcolor="#FFF">
<h2>
<%= t("#{prefix}.title") %>
</h2>
</td>
</tr>
<tr>
<td align="left" bgcolor="#FFF">
<p>
<%= t("#{prefix}.subtitle", user_name: @user.name) %>
</p>
</td>
</tr>
<tr>
<td align="left" bgcolor="#FFF">
<p>
<%= t("#{prefix}.body", plan_name: @user.plan_name) %>
</p>
</td>
</tr>
<tr>
<td align="left" bgcolor="#FFF">
<small>
<%= t("#{prefix}.footer") %>
</small>
</td>
</tr>
</tbody>
</table>
Why the `prefix approach
- Cleaner Templates: Your
.html.erb
files become significantly less verbose. - Easier Maintenance: Updating a prefix is quick and straightforward.
Top comments (2)
This is a good idea.
The other option is to Organize Your Local Files.
This could simplify your string
mailers.sample_mailer.welcome_email.title
to.welcome_email.title
, which is more manageable.Thanks a lot for the comment, @eclecticcoding
In a situation that I got into an ongoing project, I was faced with a deeply nested view mailer and the locales reflected that. Anyway, in order to get the values from the locales, a long path was required at the end.