Как изменить регистр интерполированных переменных в Rails файле локали?
Использование Rails 3.1.3 с Ruby 1.9.3p0.
Я обнаружил, что по умолчанию Rails не использует случай предложения для кнопок формы. Например, вместо кнопки "Обновить пользователя" она генерирует кнопку "Обновить пользователя".
Имена кнопок взяты из файла локали ActionView. Есть ли способ создать значение по умолчанию, которое уменьшает имя модели? Это не описано в разделе i18n раздела "Рубины на рельсах" на Interpolation, поэтому, возможно, это невозможно. Не работает следующее:
en:
helpers:
submit:
update: 'Update %{model}.downcase'
В общем, я был бы рад найти ссылку на синтаксис локальных файлов YAML. Руководство i18n охватывает некоторые синтаксисы, но было бы полезно найти документацию обо всех восклицательных знаках, разных форматах даты и времени и т.д. Или, может быть, я должен использовать Ruby Hash вместо YAML файла для этой цели?
Ответы
Ответ 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
Этот код "в значительной степени основан на расширении интерполяции Масло Матуо Мутох"
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