Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails i18n - translating text with links inside

I'd like to i18n a text that looks like this:

Already signed up? Log in!

Note that there is a link on the text. On this example it points to google - in reality it will point to my app's log_in_path.

I've found two ways of doing this, but none of them looks "right".

The first way I know involves having this my en.yml:

log_in_message: "Already signed up? <a href='{{url}}'>Log in!</a>" 

And in my view:

<p> <%= t('log_in_message', :url => login_path) %> </p> 

This works, but having the <a href=...</a> part on the en.yml doesn't look very clean to me.

The other option I know is using localized views - login.en.html.erb, and login.es.html.erb.

This also doesn't feel right since the only different line would be the aforementioned one; the rest of the view (~30 lines) would be repeated for all views. It would not be very DRY.

I guess I could use "localized partials" but that seems too cumberstone; I think I prefer the first option to having so many tiny view files.

So my question is: is there a "proper" way to implement this?

like image 429
kikito Avatar asked Mar 30 '10 08:03

kikito


2 Answers

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> 
like image 115
Simone Carletti Avatar answered Oct 04 '22 16:10

Simone Carletti


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.

like image 26
holli Avatar answered Oct 04 '22 15:10

holli