rails multi locales language i18n ruby-on-rails internationalization

ruby-on-rails - multi - rails translation interpolation



rails i18n-traducción de texto con enlaces dentro (9)

¿Por qué no usar de la primera manera, pero dividirlo como

log_in_message: Already signed up? log_in_link_text: Log in!

Y entonces

<p> <%= t(''log_in_message'') %> <%= link_to t(''log_in_link_text''), login_path %> </p>

Me gustaría encontrar un texto que se vea así:

¿Ya estás registrado? ¡Iniciar sesión!

Tenga en cuenta que hay un enlace en el texto. En este ejemplo, apunta a google; en realidad, apuntará a log_in_path mi aplicación.

He encontrado dos formas de hacerlo, pero ninguno de ellos se ve "bien".

La primera forma que conozco implica tener este mi en.yml :

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

Y en mi opinión:

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

Esto funciona , pero tener la <a href=...</a> parte en el en.yml no me parece muy limpio.

La otra opción que conozco es usar vistas localizadas : login.en.html.erb y login.es.html.erb .

Esto tampoco se siente bien ya que la única línea diferente sería la mencionada; el resto de la vista (~ 30 líneas) se repetiría para todas las vistas. No sería muy seco

Creo que podría usar "parciales localizados", pero parece demasiado engorroso; Creo que prefiero la primera opción para tener tantos archivos de vista pequeños.

Entonces mi pregunta es: ¿hay una forma "adecuada" de implementar esto?


Creo que una forma simple de hacerlo es simplemente haciendo:

<%= link_to some_path do %> <%= t ''.some_locale_key'' %> <% end %>


En en.yml

registration: terms: text: "I do agree with the terms and conditions: %{gtc} / %{stc}" gtc: "GTC" stc: "STC"

En de.yml

registration: terms: text: "Ich stimme den Geschäfts- und Nutzungsbedingungen zu: %{gtc} / %{stc}" gtc: "AGB" stc: "ANB"

en new.html.erb [assume]

<%= t( ''registration.terms.text'', gtc: link_to(t(''registration.terms.gtc''), terms_and_conditions_home_index_url + "?tab=gtc"), stc: link_to(t(''registration.terms.stc''), terms_and_conditions_home_index_url + "?tab=stc") ).html_safe %>


Muchas gracias, holli, por compartir este enfoque. Funciona como un encanto para mí. Te votaría si pudiera, pero esta es mi primera publicación, así que me falta la reputación adecuada ... Como una pieza adicional al rompecabezas: el problema que me di cuenta con tu enfoque es que todavía no funcionará desde adentro el controlador. Investigué un poco y combiné tu enfoque con el de Glenn en rubypond .

Aquí es lo que se me ocurrió:

Ver ayudante, por ejemplo, application_helper.rb

def render_flash_messages messages = flash.collect do |key, value| content_tag(:div, flash_message_with_link(key, value), :class => "flash #{key}") unless key.to_s =~ /_link$/i end messages.join.html_safe end def flash_message_with_link(key, value) link = flash["#{key}_link".to_sym] link.nil? ? value : string_with_link(value, link).html_safe end # Converts # "string with __link__ in the middle." to # "string with #{link_to(''link'', link_url, link_options)} in the middle." # --> see http://.com/questions/2543936/rails-i18n-translating-text-with-links-inside (holli) def string_with_link(str, link_url, link_options = {}) match = str.match(/__([^_]{2,30})__/) if !match.blank? $` + 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

En el controlador:

flash.now[:alert] = t("path.to.translation") flash.now[:alert_link] = here_comes_the_link_path # or _url

En el locale.yml:

path: to: translation: "string with __link__ in the middle"

En la vista:

<%= render_flash_messages %>

Espero que este post me gane la reputación de votarte, holli :) Cualquier comentario es bienvenido.


Quería un poco más de flexibilidad que simplemente agregar enlaces a mensajes flash de archivos YAML (por ejemplo, el nombre de usuario registrado, etc.), así que en su lugar quería usar la notación ERB en la cadena.

Como estoy usando bootstrap_flash , modifiqué el código auxiliar de la siguiente manera para decodificar las cadenas ERB antes de mostrar:

require ''erb'' module BootstrapFlashHelper ALERT_TYPES = [:error, :info, :success, :warning] unless const_defined?(:ALERT_TYPES) def bootstrap_flash flash_messages = [] flash.each do |type, message| # Skip empty messages, e.g. for devise messages set to nothing in a locale file. next if message.blank? type = type.to_sym type = :success if type == :notice type = :error if type == :alert next unless ALERT_TYPES.include?(type) Array(message).each do |msg| begin msg = ERB.new(msg).result(binding) if msg rescue Exception=>e puts e.message puts e.backtrace end text = content_tag(:div, content_tag(:button, raw("&times;"), :class => "close", "data-dismiss" => "alert") + msg.html_safe, :class => "alert fade in alert-#{type}") flash_messages << text if msg end end flash_messages.join("/n").html_safe end end

Entonces es posible usar cadenas como las siguientes (usando el dispositivo):

signed_in: "Welcome back <%= current_user.first_name %>! <%= link_to /"Click here/", account_path %> for your account."

Esto puede no funcionar para todas las situaciones y puede haber un argumento de que las definiciones de código y cadena no deben mezclarse (especialmente desde la perspectiva DRY), pero esto parece funcionar bien para mí. El código debe ser adaptable para muchas otras situaciones, los bits importantes son los siguientes:

require ''erb'' .... begin msg = ERB.new(msg).result(binding) if msg rescue Exception=>e puts e.message puts e.backtrace end


Separar el texto y el enlace en el archivo locale.yml funciona por un tiempo, pero con el texto más largo es difícil de traducir y mantener ya que el enlace está en un elemento de traducción separado (como en la respuesta de Simones). Si comienza a tener muchas cadenas / traducciones con enlaces, puede secarlo un poco más.

Hice una ayuda en mi 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

En mi en.yml:

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

Y en mi opinión:

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

De esta forma, es más fácil traducir mensajes, ya que también el texto del enlace está claramente definido en los archivos locale.yml.


Tomé la solución hollis e hice github.com/iGEL/it sacó. Veamos un ejemplo:

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

Y entonces

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

Para obtener más detalles, consulte github.com/iGEL/it .


Tuvimos lo siguiente:

module I18nHelpers def translate key, options={}, &block s = super key, options # Default translation if block_given? String.new(ERB::Util.html_escape(s)).gsub(/%/|([^/|]*)/|/){ capture($1, &block) # Pass in what''s between the markers }.html_safe else s end end alias :t :translate end

o más explícitamente:

module I18nHelpers # Allows an I18n to include the special %|something| marker. # "something" will then be passed in to the given block, which # can generate whatever HTML is needed. # # Normal and _html keys are supported. # # Multiples are ok # # mykey: "Click %|here| and %|there|" # # Nesting should work too. # def translate key, options={}, &block s = super key, options # Default translation if block_given? # Escape if not already raw HTML (html_escape won''t escape if already html_safe) s = ERB::Util.html_escape(s) # ActiveSupport::SafeBuffer#gsub broken, so convert to String. # See https://github.com/rails/rails/issues/1555 s = String.new(s) # Find the %|| pattern to substitute, then replace it with the block capture s = s.gsub /%/|([^/|]*)/|/ do capture($1, &block) # Pass in what''s between the markers end # Mark as html_safe going out s = s.html_safe end s end alias :t :translate end

luego en ApplicationController.rb solo

class ApplicationController < ActionController::Base helper I18nHelpers

Dada una clave en el archivo en.yml como

mykey: "Click %|here|!"

se puede usar en ERB como

<%= t ''.mykey'' do |text| %> <%= link_to text, ''http://foo.com'' %> <% end %>

debería generar

Click <a href="http://foo.com">here</a>!


log_in_message_html: "This is a text, with a %{href} inside." log_in_href: "link" <p> <%= t("log_in_message_html", :href => link_to(t("log_in_href"), login_path)) %> </p>