rails i18n - translating text with links inside

en.yml

log_in_message_html: "This is a text, with a %{href} inside."
log_in_href: "link"

login.html.erb

<p> <%= t("log_in_message_html", href: link_to(t("log_in_href"), login_path)) %> </p>

Separating text and link in locale.yml file works for a while but with longer text those are hard to translate and maintain as the link is in separate translation-item (as in Simones answer). If you start having many strings/translations with links you can dry it a bit more.

I made one helper in my application_helper.rb:

# Converts
# "string with __link__ in the middle." to
# "string with #{link_to('link', link_url, link_options)} in the middle."
def string_with_link(str, link_url, link_options = {})
  match = str.match(/__([^_]{2,30})__/)
  if !match.blank?
    raw($` + link_to($1, link_url, link_options) + $')
  else
    raise "string_with_link: No place for __link__ given in #{str}" if Rails.env.test?
    nil
  end
end

In my en.yml:

log_in_message: "Already signed up? __Log in!__"

And in my views:

<p><%= string_with_link(t('.log_in_message'), login_path) %></p>

This way it's easier to translate messages as also the link text is clearly defined in the locale.yml-files.


I took hollis solution and made a gem called it out of it. Let's look at an example:

log_in_message: "Already signed up? %{login:Log in!}"

And then

<p><%=t_link "log_in_message", :login => login_path %></p>

For more details, see https://github.com/iGEL/it.