2012-03-10 17 views
11

Usando Rails 3.1.3 con Ruby 1.9.3p0.¿Cómo cambiar el caso de las variables interpoladas en el archivo de configuración regional de Rails?

Descubrí que, de forma predeterminada, Rails no usa el caso de oraciones para los botones de formulario. Por ejemplo, en lugar de un botón "Actualizar usuario", genera un botón "Actualizar usuario".

Los nombres de los botones provienen del ActionView locale file. ¿Hay alguna manera de crear un valor predeterminado que rechace el nombre del modelo? Esto no está cubierto en la sección de Ruby on Rails Guides i18n en Interpolation así que tal vez no sea posible. El siguiente no funciona:

en: 
    helpers: 
    submit: 
     update: 'Update %{model}.downcase' 

En general, yo estaría contento de encontrar una referencia para la sintaxis de los archivos YAML de configuración regional. La guía i18n cubre parte de la sintaxis, pero sería útil encontrar documentación sobre todos los signos de exclamación, varios formatos de fecha/hora, etc. ¿O tal vez debería usar un Ruby Hash en lugar de un archivo YAML para este propósito?

Respuesta

8

Después de seguir investigando, he llegado a la conclusión de que este tipo de operación en valores interpolados no es posible, al menos utilizando un archivo local YAML.

YAML se documenta aquí y no soporta las operaciones de cadena:
http://www.yaml.org/spec/1.2/spec.html

La página principal sobre el Ruby localización está aquí:
http://ruby-i18n.org/wiki

A partir de ahí, nos encontramos con el código de la I18n por defecto joya y profundizar en el código de interpolación. Utiliza sprintf hacer la interpolación:
https://github.com/svenfuchs/i18n/blob/master/lib/i18n/interpolate/ruby.rb

que el código es "fuertemente basada en gettext cadena de extensión de interpolación de Masao Mutoh":
http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb

Esa extensión tiene un ejemplo de formateo números:

For strings. 
"%{firstname}, %{familyname}" % {:firstname => "Masao", :familyname => "Mutoh"} 

With field type to specify format such as d(decimal), f(float),... 
"%<age>d, %<weight>.1f" % {:age => 10, :weight => 43.4} 

La extensión se refiere a [Ruby] "Kernel::sprintf para detalles de la cadena de formato":
http://www.ruby-doc.org/core-1.9.2/Kernel.html#method-i-sprintf

En ese documento en sprintf, hay un montón de formas de formatear números, pero no hay operaciones para cambiar el caso de las cadenas.

1

He resuelto este problema cambiando la interpolación I18n. Coloque el código siguiente en el directorio de inicializadores:

module I18n 
    # Implemented to support method call on translation keys 
    INTERPOLATION_WITH_METHOD_PATTERN = Regexp.union(
    /%%/, 
    /%\{(\w+)\}/,        # matches placeholders like "%{foo}" 
    /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/, # matches placeholders like "%<foo>.d" 
    /%\{(\w+)\.(\w+)\}/,       # matches placeholders like "%{foo.upcase}" 
) 

    class << self 
    def interpolate_hash(string, values) 
     string.gsub(INTERPOLATION_WITH_METHOD_PATTERN) do |match| 
     if match == '%%' 
      '%' 
     else 
      key = ($1 || $2 || $4).to_sym 
      value = values.key?(key) ? values[key] : raise(MissingInterpolationArgument.new(values, string)) 
      value = value.call(values) if value.respond_to?(:call) 
      $3 ? sprintf("%#{$3}", value) : ($5 ? value.send($5) : value) 
     end 
     end 
    end 
    end 
end 

Ahora bien, esto es lo que puede hacer en su archivo de configuración regional:

create: 'Opprett %{model.downcase}' 

y probarlo:

require 'test_helper' 

class I18nTest < ActiveSupport::TestCase 

    should 'interpolate as usual' do 
    assert_equal 'Show Customer', I18n.interpolate("Show %{model}", model: 'Customer') 
    end 

    should 'interpolate with number formatting' do 
    assert_equal 'Show many 100', I18n.interpolate("Show many %<kr>2d", kr: 100) 
    assert_equal 'Show many abc', I18n.interpolate("Show many %<str>3.3s", str: 'abcde') 
    end 

    should 'support method execution' do 
    assert_equal 'Show customer', I18n.interpolate("Show %{model.downcase}", model: 'Customer') 
    end 

end 
Cuestiones relacionadas