¿Cómo cambiar el caso de las variables interpoladas en el archivo de configuración regional de Rails?

Using Rails 3.1.3 with Ruby 1.9.3p0.

I've discovered that by default, Rails does not use sentence case for form buttons. For example, instead of an "Update user" button, it generates an "Update User" button.

The button names come from the ActionView locale file. Is there a way to create a default that downcases the model name? This is not covered in the Ruby on Rails Guides i18n section on Interpolación so maybe it is not possible. The following doesn't work:

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

In general, I'd be glad to find a reference for the syntax of the locale YAML files. The i18n guide covers some of the syntax, but it would be helpful to find documentation on all the exclamation points, various date/time formats, etc. Or maybe I should be using a Ruby Hash instead of a YAML file for this purpose?

preguntado el 10 de marzo de 12 a las 00:03

2 Respuestas

After further research, I've concluded that this kind of operation on interpolated values is not possible, at least using a YAML locale file.

YAML is documented here and doesn't support string operations:
http://www.yaml.org/spec/1.2/spec.html

The main page on Ruby localization is here:
http://ruby-i18n.org/wiki

From there, we find the code for the default I18n gem and drill down to the interpolation code. It uses sprintf to do the interpolation:
https://github.com/svenfuchs/i18n/blob/master/lib/i18n/interpolate/ruby.rb

That code is "heavily based on Masao Mutoh's gettext String interpolation extension":
http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb

That extension has an example of formatting los 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}

The extension refers to the [Ruby] "Kernel::sprintf for details of the format string":
http://www.ruby-doc.org/core-1.9.2/Kernel.html#method-i-sprintf

In that doc on sprintf, there are lots of ways to format numbers, but no operations for changing the case of strings.

respondido 20 mar '12, 00:03

I have solved this problem by changing the I18n interpolation. Put the following code in your initializers directory:

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

Now, this is what you can do in your locale file:

create: 'Opprett %{model.downcase}'

y pruébalo:

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

respondido 19 nov., 14:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.