提交 13af5ace 编写于 作者: J José Valim

Merge pull request #7197 from davidcelis/i18n_inflector

Make ActiveSupport::Inflector locale aware and multilingual
...@@ -13,6 +13,11 @@ class String ...@@ -13,6 +13,11 @@ class String
# the singular form will be returned if <tt>count == 1</tt>. # the singular form will be returned if <tt>count == 1</tt>.
# For any other value of +count+ the plural will be returned. # For any other value of +count+ the plural will be returned.
# #
# If the optional parameter +locale+ is specified,
# the word will be pluralized as a word of that language.
# By default, this parameter is set to <tt>:en</tt>.
# You must define your own inflection rules for languages other than English.
#
# 'post'.pluralize # => "posts" # 'post'.pluralize # => "posts"
# 'octopus'.pluralize # => "octopi" # 'octopus'.pluralize # => "octopi"
# 'sheep'.pluralize # => "sheep" # 'sheep'.pluralize # => "sheep"
...@@ -21,15 +26,23 @@ class String ...@@ -21,15 +26,23 @@ class String
# 'CamelOctopus'.pluralize # => "CamelOctopi" # 'CamelOctopus'.pluralize # => "CamelOctopi"
# 'apple'.pluralize(1) # => "apple" # 'apple'.pluralize(1) # => "apple"
# 'apple'.pluralize(2) # => "apples" # 'apple'.pluralize(2) # => "apples"
def pluralize(count = nil) # 'ley'.pluralize(:es) # => "leyes"
# 'ley'.pluralize(1, :es) # => "ley"
def pluralize(count = nil, locale = :en)
locale = count if count.is_a?(Symbol)
if count == 1 if count == 1
self self
else else
ActiveSupport::Inflector.pluralize(self) ActiveSupport::Inflector.pluralize(self, locale)
end end
end end
# The reverse of +pluralize+, returns the singular form of a word in a string. # The reverse of +pluralize+, returns the singular form of a word in a string.
#
# If the optional parameter +locale+ is specified,
# the word will be singularized as a word of that language.
# By default, this paramter is set to <tt>:en</tt>.
# You must define your own inflection rules for languages other than English.
# #
# 'posts'.singularize # => "post" # 'posts'.singularize # => "post"
# 'octopi'.singularize # => "octopus" # 'octopi'.singularize # => "octopus"
...@@ -37,8 +50,9 @@ def pluralize(count = nil) ...@@ -37,8 +50,9 @@ def pluralize(count = nil)
# 'word'.singularize # => "word" # 'word'.singularize # => "word"
# 'the blue mailmen'.singularize # => "the blue mailman" # 'the blue mailmen'.singularize # => "the blue mailman"
# 'CamelOctopi'.singularize # => "CamelOctopus" # 'CamelOctopi'.singularize # => "CamelOctopus"
def singularize # 'leyes'.singularize(:es) # => "ley"
ActiveSupport::Inflector.singularize(self) def singularize(locale = :en)
ActiveSupport::Inflector.singularize(self, locale)
end end
# +constantize+ tries to find a declared constant with the name specified # +constantize+ tries to find a declared constant with the name specified
......
require 'active_support/inflector/inflections' require 'active_support/inflector/inflections'
module ActiveSupport module ActiveSupport
Inflector.inflections do |inflect| Inflector.inflections(:en) do |inflect|
inflect.plural(/$/, 's') inflect.plural(/$/, 's')
inflect.plural(/s$/i, 's') inflect.plural(/s$/i, 's')
inflect.plural(/^(ax|test)is$/i, '\1es') inflect.plural(/^(ax|test)is$/i, '\1es')
......
require 'active_support/core_ext/array/prepend_and_append' require 'active_support/core_ext/array/prepend_and_append'
require 'active_support/i18n'
module ActiveSupport module ActiveSupport
module Inflector module Inflector
extend self extend self
# A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional # A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
# inflection rules. # inflection rules. If passed an optional locale, rules for other languages can be specified. The default locale is
# <tt>:en</tt>. Only rules for English are provided.
# #
# ActiveSupport::Inflector.inflections do |inflect| # ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.plural /^(ox)$/i, '\1\2en' # inflect.plural /^(ox)$/i, '\1\2en'
# inflect.singular /^(ox)en/i, '\1' # inflect.singular /^(ox)en/i, '\1'
# #
...@@ -20,8 +22,9 @@ module Inflector ...@@ -20,8 +22,9 @@ module Inflector
# pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may # pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
# already have been loaded. # already have been loaded.
class Inflections class Inflections
def self.instance def self.instance(locale = :en)
@__instance__ ||= new @__instance__ ||= Hash.new { |h, k| h[k] = new }
@__instance__[locale]
end end
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex
...@@ -160,16 +163,18 @@ def clear(scope = :all) ...@@ -160,16 +163,18 @@ def clear(scope = :all)
end end
# Yields a singleton instance of Inflector::Inflections so you can specify additional # Yields a singleton instance of Inflector::Inflections so you can specify additional
# inflector rules. # inflector rules. If passed an optional locale, rules for other languages can be specified.
# If not specified, defaults to <tt>:en</tt>. Only rules for English are provided.
#
# #
# ActiveSupport::Inflector.inflections do |inflect| # ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.uncountable "rails" # inflect.uncountable "rails"
# end # end
def inflections def inflections(locale = :en)
if block_given? if block_given?
yield Inflections.instance yield Inflections.instance(locale)
else else
Inflections.instance Inflections.instance(locale)
end end
end end
end end
......
...@@ -10,31 +10,41 @@ module ActiveSupport ...@@ -10,31 +10,41 @@ module ActiveSupport
# #
# The Rails core team has stated patches for the inflections library will not be accepted # The Rails core team has stated patches for the inflections library will not be accepted
# in order to avoid breaking legacy applications which may be relying on errant inflections. # in order to avoid breaking legacy applications which may be relying on errant inflections.
# If you discover an incorrect inflection and require it for your application, you'll need # If you discover an incorrect inflection and require it for your application or wish to
# to correct it yourself (explained below). # define rules for languages other than English, please correct or add them yourself (explained below).
module Inflector module Inflector
extend self extend self
# Returns the plural form of the word in the string. # Returns the plural form of the word in the string.
# #
# If passed an optional +locale+ parameter, the word will be
# pluralized using rules defined for that language. By default,
# this parameter is set to <tt>:en</tt>.
#
# "post".pluralize # => "posts" # "post".pluralize # => "posts"
# "octopus".pluralize # => "octopi" # "octopus".pluralize # => "octopi"
# "sheep".pluralize # => "sheep" # "sheep".pluralize # => "sheep"
# "words".pluralize # => "words" # "words".pluralize # => "words"
# "CamelOctopus".pluralize # => "CamelOctopi" # "CamelOctopus".pluralize # => "CamelOctopi"
def pluralize(word) # "ley".pluralize(:es) # => "leyes"
apply_inflections(word, inflections.plurals) def pluralize(word, locale = :en)
apply_inflections(word, inflections(locale).plurals)
end end
# The reverse of +pluralize+, returns the singular form of a word in a string. # The reverse of +pluralize+, returns the singular form of a word in a string.
# #
# If passed an optional +locale+ parameter, the word will be
# pluralized using rules defined for that language. By default,
# this parameter is set to <tt>:en</tt>.
#
# "posts".singularize # => "post" # "posts".singularize # => "post"
# "octopi".singularize # => "octopus" # "octopi".singularize # => "octopus"
# "sheep".singularize # => "sheep" # "sheep".singularize # => "sheep"
# "word".singularize # => "word" # "word".singularize # => "word"
# "CamelOctopi".singularize # => "CamelOctopus" # "CamelOctopi".singularize # => "CamelOctopus"
def singularize(word) # "leyes".singularize(:es) # => "ley"
apply_inflections(word, inflections.singulars) def singularize(word, locale = :en)
apply_inflections(word, inflections(locale).singulars)
end end
# By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+ # By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
......
...@@ -354,6 +354,35 @@ def test_clear_#{inflection_type} ...@@ -354,6 +354,35 @@ def test_clear_#{inflection_type}
RUBY RUBY
end end
def test_inflector_locality
ActiveSupport::Inflector.inflections(:es) do |inflect|
inflect.plural(/$/, 's')
inflect.plural(/z$/i, 'ces')
inflect.singular(/s$/, '')
inflect.singular(/es$/, '')
inflect.irregular('el', 'los')
end
assert_equal('hijos', 'hijo'.pluralize(:es))
assert_equal('luces', 'luz'.pluralize(:es))
assert_equal('luzs', 'luz'.pluralize)
assert_equal('sociedad', 'sociedades'.singularize(:es))
assert_equal('sociedade', 'sociedades'.singularize)
assert_equal('los', 'el'.pluralize(:es))
assert_equal('els', 'el'.pluralize)
ActiveSupport::Inflector.inflections(:es) { |inflect| inflect.clear }
assert ActiveSupport::Inflector.inflections(:es).plurals.empty?
assert ActiveSupport::Inflector.inflections(:es).singulars.empty?
assert !ActiveSupport::Inflector.inflections.plurals.empty?
assert !ActiveSupport::Inflector.inflections.singulars.empty?
end
def test_clear_all def test_clear_all
with_dup do with_dup do
ActiveSupport::Inflector.inflections do |inflect| ActiveSupport::Inflector.inflections do |inflect|
...@@ -467,7 +496,7 @@ def test_clear_with_default ...@@ -467,7 +496,7 @@ def test_clear_with_default
# there are module functions that access ActiveSupport::Inflector.inflections, # there are module functions that access ActiveSupport::Inflector.inflections,
# so we need to replace the singleton itself. # so we need to replace the singleton itself.
def with_dup def with_dup
original = ActiveSupport::Inflector.inflections original = ActiveSupport::Inflector::Inflections.instance_variable_get(:@__instance__)
ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, original.dup) ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, original.dup)
ensure ensure
ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, original) ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, original)
......
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
# Add new inflection rules using the following format # Add new inflection rules using the following format. Inflections
# (all these examples are active by default): # are locale specific, and you may define rules for as many different
# ActiveSupport::Inflector.inflections do |inflect| # locales as you wish. All of these examples are active by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.plural /^(ox)$/i, '\1en' # inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1' # inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people' # inflect.irregular 'person', 'people'
...@@ -10,6 +11,6 @@ ...@@ -10,6 +11,6 @@
# end # end
# #
# These inflection rules are supported but not enabled by default: # These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections do |inflect| # ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.acronym 'RESTful' # inflect.acronym 'RESTful'
# end # end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册