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 Interpolation 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?
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 numbers:
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.
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}'
and test it:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With