diff --git a/lib/i18n/config.rb b/lib/i18n/config.rb index 0a232a0e..7cde3409 100644 --- a/lib/i18n/config.rb +++ b/lib/i18n/config.rb @@ -136,5 +136,18 @@ def enforce_available_locales def enforce_available_locales=(enforce_available_locales) @@enforce_available_locales = enforce_available_locales end + + # Allows clients to provide custom placeholders. + # + # E.g. using {{}} as a placeholder: "{{hello}}, world!" + # I18n.config.interpolation_patterns << /\{\{(\w+)\}\}/ + def interpolation_patterns + @@interpolation_patterns ||= I18n::INTERPOLATION_PATTERNS + end + + # Sets interpolation patterns. Expect an array of patterns. + def interpolation_patterns=(interpolation_patterns) + @@interpolation_patterns = interpolation_patterns + end end end diff --git a/lib/i18n/interpolate/ruby.rb b/lib/i18n/interpolate/ruby.rb index 442677f2..34dfa1f2 100644 --- a/lib/i18n/interpolate/ruby.rb +++ b/lib/i18n/interpolate/ruby.rb @@ -2,11 +2,12 @@ # http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb module I18n - INTERPOLATION_PATTERN = Regexp.union( + INTERPOLATION_PATTERNS = [ /%%/, /%\{(\w+)\}/, # matches placeholders like "%{foo}" /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%.d" - ) + ] + INTERPOLATION_PATTERN = Regexp.union(INTERPOLATION_PATTERNS) class << self # Return String or raises MissingInterpolationArgument exception. @@ -18,18 +19,20 @@ def interpolate(string, values) end def interpolate_hash(string, values) - string.gsub(INTERPOLATION_PATTERN) do |match| - if match == '%%' + pattern = Regexp.union(config.interpolation_patterns) + string.gsub(pattern) do |match_str| + if match_str == '%%' '%' else - key = ($1 || $2).to_sym + placeholder, format = match_str.match(pattern).captures.reject(&:nil?) + key = placeholder.to_sym value = if values.key?(key) values[key] else config.missing_interpolation_argument_handler.call(key, values, string) end value = value.call(values) if value.respond_to?(:call) - $3 ? sprintf("%#{$3}", value) : value + format ? sprintf("%#{format}", value) : value end end end diff --git a/test/i18n/interpolate_test.rb b/test/i18n/interpolate_test.rb index 4bc63926..00cbf6d1 100644 --- a/test/i18n/interpolate_test.rb +++ b/test/i18n/interpolate_test.rb @@ -78,3 +78,20 @@ def teardown I18n.interpolate("%{first} %{last}", :first => 'Masao') end end + +class I18nCustomInterpolationPatternTest < I18n::TestCase + def setup + super + @old_interpolation_patterns = I18n.config.interpolation_patterns + I18n.config.interpolation_patterns << /\{\{(\w+)\}\}/ + end + + def teardown + I18n.config.interpolation_patterns = @old_interpolation_patterns + super + end + + test "String interpolation can use custom interpolation pattern" do + assert_equal "Masao Mutoh", I18n.interpolate("{{first}} {{last}}", :first => 'Masao', :last => 'Mutoh') + end +end