【问题标题】:How to change case of interpolated variables in Rails locale file?如何更改 Rails 语言环境文件中插值变量的大小写?
【发布时间】:2012-03-10 00:46:46
【问题描述】:

在 Ruby 1.9.3p0 中使用 Rails 3.1.3。

我发现默认情况下,Rails 不对表单按钮使用句子大小写。例如,它不会生成“更新用户”按钮,而是生成“更新用户”按钮。

按钮名称来自ActionView locale file。有没有办法创建一个缩小模型名称的默认值?这在Interpolation 的 Ruby on Rails Guides i18n 部分中没有涉及,所以也许这是不可能的。以下不起作用:

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

一般来说,我很乐意找到有关语言环境 YAML 文件语法的参考。 i18n 指南涵盖了一些语法,但查找有关所有感叹号、各种日期/时间格式等的文档会很有帮助。或者我应该为此目的使用 Ruby 哈希而不是 YAML 文件?

【问题讨论】:

    标签: ruby-on-rails-3.1 internationalization


    【解决方案1】:

    经过进一步研究,我得出结论,这种对插值的操作是不可能的,至少使用 YAML 语言环境文件是不可能的。

    YAML 记录在这里,不支持字符串操作:
    http://www.yaml.org/spec/1.2/spec.html

    Ruby 本地化主页在这里:
    http://ruby-i18n.org/wiki

    从那里,我们找到默认 I18n gem 的代码并深入到插值代码。它使用sprintf 进行插值:
    https://github.com/svenfuchs/i18n/blob/master/lib/i18n/interpolate/ruby.rb

    该代码“很大程度上基于 Masao Mutoh 的 gettext 字符串插值扩展”:
    http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb

    那个扩展有一个格式化数字的例子:

    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}
    

    扩展名参考[Ruby]“Kernel::sprintf获取格式字符串的详细信息”:
    http://www.ruby-doc.org/core-1.9.2/Kernel.html#method-i-sprintf

    sprintf 上的那个文档中,有很多格式化数字的方法,但没有改变字符串大小写的操作。

    【讨论】:

      【解决方案2】:

      我通过改变 I18n 插值解决了这个问题。将以下代码放在初始化程序目录中:

      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
      

      现在,您可以在语言环境文件中执行以下操作:

      create: 'Opprett %{model.downcase}'
      

      并测试它:

      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
      

      【讨论】:

        猜你喜欢
        • 2020-09-10
        • 1970-01-01
        • 2019-03-03
        • 1970-01-01
        • 2019-02-27
        • 1970-01-01
        • 2014-09-01
        • 2013-04-27
        • 2023-03-24
        相关资源
        最近更新 更多