rich_i18n 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/CHANGELOG +19 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +269 -0
- data/Rakefile +42 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/rich/i18n.rb +11 -0
- data/lib/rich/i18n/actionpack.rb +4 -0
- data/lib/rich/i18n/actionpack/action_controller/dispatcher.rb +12 -0
- data/lib/rich/i18n/actionpack/action_view/base.rb +13 -0
- data/lib/rich/i18n/actionpack/action_view/sanitizor.rb +61 -0
- data/lib/rich/i18n/core.rb +8 -0
- data/lib/rich/i18n/core/array.rb +8 -0
- data/lib/rich/i18n/core/array/merging.rb +29 -0
- data/lib/rich/i18n/core/enriched_string.rb +28 -0
- data/lib/rich/i18n/core/enumerable/methods.rb +16 -0
- data/lib/rich/i18n/core/erb.rb +6 -0
- data/lib/rich/i18n/core/erb/output.rb +22 -0
- data/lib/rich/i18n/core/hash.rb +6 -0
- data/lib/rich/i18n/core/nil_class.rb +8 -0
- data/lib/rich/i18n/core/object.rb +6 -0
- data/lib/rich/i18n/core/object/output.rb +20 -0
- data/lib/rich/i18n/core/string.rb +10 -0
- data/lib/rich/i18n/core/string/enrichments.rb +68 -0
- data/lib/rich/i18n/core/string/inflections.rb +42 -0
- data/lib/rich/i18n/core/string/internationalization.rb +82 -0
- data/lib/rich/i18n/core/symbol.rb +6 -0
- data/lib/rich/i18n/core/symbol/internationalization.rb +16 -0
- data/lib/rich/i18n/engine.rb +31 -0
- data/lib/rich/i18n/formtastic.rb +51 -0
- data/lib/rich_i18n.rb +5 -0
- data/locales/nl.yml +14 -0
- data/rails/init.rb +1 -0
- data/tasks/rich_i18n_tasks.rake +11 -0
- data/test/core/string/inflections_test.rb +42 -0
- data/test/core/string/internationalization_test.rb +23 -0
- data/test/engine_test.rb +20 -0
- data/test/locales/nl/internationalization_test.rb +47 -0
- data/test/setup.rb +14 -0
- data/test/test_helper.rb +5 -0
- data/uninstall.rb +1 -0
- metadata +136 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module Rich
|
3
|
+
module I18n
|
4
|
+
module Core
|
5
|
+
module Array
|
6
|
+
module Merging
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
base.class_eval do
|
10
|
+
alias_method_chain :join, :rich_i18n
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def join_with_rich_i18n(sep = "")
|
15
|
+
if size == 1 && first.is_a?(EnrichedString)
|
16
|
+
first
|
17
|
+
else
|
18
|
+
merged_strings = dup
|
19
|
+
result = join_without_rich_i18n(sep)
|
20
|
+
result.merged_strings = merged_strings
|
21
|
+
result
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
module Rich
|
3
|
+
module I18n
|
4
|
+
module Core
|
5
|
+
class EnrichedString < ::String
|
6
|
+
|
7
|
+
def initialize(s = "", meta_data = nil)
|
8
|
+
super s
|
9
|
+
@meta_data = meta_data || (s.meta_data.dup unless (s.meta_data.nil? rescue true)) || {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize_copy_with_rich_i18n(s)
|
13
|
+
result = super(s)
|
14
|
+
result.meta_data = self.meta_data.dup
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_es
|
18
|
+
@meta_data.filled? and ::Rich::I18n::Engine.can_enrich_output? ?
|
19
|
+
"<i18n #{@meta_data.collect{|k, v| "data-#{k}=#{v.inspect}"}.join(" ")}>#{to_s}</i18n>" :
|
20
|
+
to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
EnrichedString = Rich::I18n::Core::EnrichedString
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
module Rich
|
3
|
+
module I18n
|
4
|
+
module Core
|
5
|
+
module ERB
|
6
|
+
module Output
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
base.class_eval do
|
10
|
+
alias_method_chain :push, :rich_i18n
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def push_with_rich_i18n(cmd)
|
15
|
+
push_without_rich_i18n cmd.match(/^#{@compiler.insert_cmd}\(\(.*\)\.to_s\)$/) ? cmd.gsub(/to_s\)$/, "to_output)") : cmd
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
|
2
|
+
require "rich/i18n/core/string/inflections"
|
3
|
+
require "rich/i18n/core/string/internationalization"
|
4
|
+
require "rich/i18n/core/string/enrichments"
|
5
|
+
|
6
|
+
class String
|
7
|
+
include Rich::I18n::Core::String::Inflections
|
8
|
+
include Rich::I18n::Core::String::Internationalization
|
9
|
+
include Rich::I18n::Core::String::Enrichments
|
10
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
module Rich
|
3
|
+
module I18n
|
4
|
+
module Core
|
5
|
+
module String
|
6
|
+
module Enrichments
|
7
|
+
|
8
|
+
# TODO: override String interpolation (e.g. "foo #{"bar".t}")
|
9
|
+
|
10
|
+
def self.included(base)
|
11
|
+
base.class_eval do
|
12
|
+
alias_method :add_without_rich_i18n, :+
|
13
|
+
alias_method :+, :add_with_rich_i18n
|
14
|
+
alias_method_chain :concat, :rich_i18n
|
15
|
+
undef_method :<<
|
16
|
+
alias_method :<<, :concat_with_rich_i18n
|
17
|
+
|
18
|
+
alias_method_chain :initialize_copy, :rich_i18n
|
19
|
+
|
20
|
+
attr_accessor :meta_data
|
21
|
+
attr_accessor :merged_strings
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize_copy_with_rich_i18n(s)
|
26
|
+
result = initialize_copy_without_rich_i18n(s)
|
27
|
+
result.merged_strings = self.merged_strings.try :dup
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_with_rich_i18n(other)
|
31
|
+
strings, result = self.merged_strings.try(:dup) || [], add_without_rich_i18n(other)
|
32
|
+
|
33
|
+
if (result.merged_strings = strings).empty?
|
34
|
+
result.merged_strings << self.dup
|
35
|
+
end
|
36
|
+
unless other.empty?
|
37
|
+
result.merged_strings << other
|
38
|
+
end
|
39
|
+
|
40
|
+
result
|
41
|
+
end
|
42
|
+
|
43
|
+
def concat_with_rich_i18n(other_or_fixnum)
|
44
|
+
string, result = self.dup, concat_without_rich_i18n(other_or_fixnum)
|
45
|
+
|
46
|
+
if (result.merged_strings ||= []).empty? and !string.empty?
|
47
|
+
result.merged_strings << string
|
48
|
+
end
|
49
|
+
result.merged_strings << other_or_fixnum.dup unless other_or_fixnum.empty?
|
50
|
+
|
51
|
+
result
|
52
|
+
end
|
53
|
+
|
54
|
+
def enriched_string?
|
55
|
+
is_a?(EnrichedString) or (merged_strings || []).any?(&:enriched_string?)
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_output
|
59
|
+
merged_strings.blank? ?
|
60
|
+
to_es :
|
61
|
+
merged_strings.collect(&:to_output).join
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
module Rich
|
3
|
+
module I18n
|
4
|
+
module Core
|
5
|
+
module String
|
6
|
+
module Inflections
|
7
|
+
|
8
|
+
# -- start FIXME: these methods are also defined in rich_pluralization
|
9
|
+
|
10
|
+
def upcase_first
|
11
|
+
empty? ?
|
12
|
+
self :
|
13
|
+
self[0].chr.capitalize + self[1, size]
|
14
|
+
end
|
15
|
+
|
16
|
+
def cp_case(s)
|
17
|
+
send((:downcase unless s.dup.downcase!) || (:upcase unless s.dup.upcase!) || (:upcase_first unless s.dup.upcase_first!) || :to_s)
|
18
|
+
end
|
19
|
+
|
20
|
+
def upcase_first!
|
21
|
+
self == (result = upcase_first) ? nil : replace(result)
|
22
|
+
end
|
23
|
+
|
24
|
+
def cp_case!(s)
|
25
|
+
self == (result = cp_case(s)) ? nil : replace(result)
|
26
|
+
end
|
27
|
+
|
28
|
+
# -- end
|
29
|
+
|
30
|
+
def singularize!
|
31
|
+
downcase == (result = singularize).downcase ? nil : replace(result)
|
32
|
+
end
|
33
|
+
|
34
|
+
def pluralize!
|
35
|
+
downcase == (result = pluralize).downcase ? nil : replace(result)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
|
2
|
+
module Rich
|
3
|
+
module I18n
|
4
|
+
module Core
|
5
|
+
module String
|
6
|
+
module Internationalization
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
base.send :include, InstanceMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
def t(options = {})
|
14
|
+
self.split(" ").collect do |string|
|
15
|
+
key = string.include?(".") ? string.dup : "word.#{string}"
|
16
|
+
default = key.split(".").last
|
17
|
+
translating_word = key.starts_with?("word.")
|
18
|
+
|
19
|
+
key.downcase!
|
20
|
+
options[:pluralize] = "".respond_to?(:pl) && (options[:pluralize].nil? || options[:pluralize])
|
21
|
+
options[:translate_callback] ||= LOGGER_PROC if RAILS_ENV == "development"
|
22
|
+
|
23
|
+
if options.include? :default
|
24
|
+
options[:default] = [options[:default]].flatten << default.humanize
|
25
|
+
s = i18n_t key, options
|
26
|
+
s = s[:_base] if s.is_a?(Hash)
|
27
|
+
value = s.dup
|
28
|
+
else
|
29
|
+
s = i18n_t key, options.merge({:default => translating_word ? "" : default.humanize})
|
30
|
+
value = s.dup
|
31
|
+
|
32
|
+
if translating_word
|
33
|
+
unless (translated = !s.empty?) or !"".respond_to?(:pl)
|
34
|
+
key.singularize!
|
35
|
+
s = i18n_t key, options.merge({:default => ""})
|
36
|
+
value = s.dup
|
37
|
+
end
|
38
|
+
|
39
|
+
if s.empty?
|
40
|
+
s = default.humanize
|
41
|
+
value = s.dup
|
42
|
+
else
|
43
|
+
s = s.pl(options[:count]) unless !options[:pluralize] or (options[:count].nil? and default.dup.pluralize!)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
unless s.gsub!(/^=\s+/, "")
|
49
|
+
s.cp_case! options[:capitalize] ? default.capitalize : default
|
50
|
+
end
|
51
|
+
|
52
|
+
EnrichedString.new s, {:key => string, :actual_key => key, :actual_value => value}
|
53
|
+
|
54
|
+
end.join(" ")
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
RICH_I18N_OPTIONS = [:count, :pluralize, :capitalize, :translate_callback]
|
60
|
+
LOGGER_PROC = Proc.new{|translation, key, options| puts "INFO: I18n.t #{key.inspect}, #{options.inspect}"}
|
61
|
+
|
62
|
+
@@i18n_translations = {}
|
63
|
+
|
64
|
+
def i18n_t(key, opts = {})
|
65
|
+
options = opts.inject({}) do |hash, (k, v)|
|
66
|
+
hash[k] = v.is_a?(String) && v.include?("<i18n") ? v.gsub(/(\<i18n[^\>]+\>)|(\<\/i18n\>)/, "") : v unless RICH_I18N_OPTIONS.include?(k)
|
67
|
+
hash
|
68
|
+
end
|
69
|
+
|
70
|
+
k = "#{key.inspect}, #{options.inspect}"
|
71
|
+
translation = (@@i18n_translations[k] ||= I18n.t(key, options).dup)
|
72
|
+
opts[:translate_callback].try :call, translation, key, options
|
73
|
+
|
74
|
+
translation
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
module Rich
|
3
|
+
module I18n
|
4
|
+
module Engine
|
5
|
+
extend self
|
6
|
+
|
7
|
+
attr_accessor :enable_enriched_output
|
8
|
+
|
9
|
+
def init(test_class = nil)
|
10
|
+
if test_class
|
11
|
+
test_locale = test_class.name.match(/(Rich\:\:I18n\:\:Test\:\:Locales\:\:)(\w+)/).captures[1].downcase.to_sym
|
12
|
+
|
13
|
+
I18n.load_path = [File.join(File.dirname(__FILE__), "..", "..", "..", "locales", "#{test_locale}.yml")]
|
14
|
+
else
|
15
|
+
I18n.load_path += Dir[File.join(File.dirname(__FILE__), "..", "..", "..", "locales", "*.yml")]
|
16
|
+
end
|
17
|
+
|
18
|
+
I18n.backend.reload!
|
19
|
+
|
20
|
+
test_locale
|
21
|
+
end
|
22
|
+
|
23
|
+
def can_enrich_output?
|
24
|
+
!enable_enriched_output.blank? and (enable_enriched_output.is_a?(Symbol) ? (send(enable_enriched_output) rescue false) : enable_enriched_output)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Rich::I18n::Engine.init
|
@@ -0,0 +1,51 @@
|
|
1
|
+
|
2
|
+
module Rich
|
3
|
+
module I18n
|
4
|
+
module Formtastic
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.alias_method_chain :input, :enrichments
|
8
|
+
end
|
9
|
+
|
10
|
+
def input_with_enrichments(*args)
|
11
|
+
object = (@object.class.name if @object) || @object_name.match(/\[(\w+)_attributes\]/).captures.first.classify
|
12
|
+
method_arg = args.shift
|
13
|
+
method = method_arg.to_s
|
14
|
+
options = args.extract_options!
|
15
|
+
wrapper_tag = options.delete(:wrapper_tag)
|
16
|
+
|
17
|
+
unless options.include?(:label)
|
18
|
+
keys = [:"label.#{object}.#{method}", :"label.#{method}", :"word.#{method}"]
|
19
|
+
|
20
|
+
if @options.include?(:name)
|
21
|
+
keys.unshift :"label.forms.(#{@options[:name]}).#{method}"
|
22
|
+
keys.unshift :"label.forms.(#{@options[:name]}).#{object}.#{method}"
|
23
|
+
end
|
24
|
+
|
25
|
+
options[:label] = keys.shift.t(:default => keys, :capitalize => true).to_output
|
26
|
+
end
|
27
|
+
|
28
|
+
unless options.include?(:seatholder)
|
29
|
+
keys = [:"seatholder.#{object}.#{method}", :"seatholder.#{method}", ""]
|
30
|
+
|
31
|
+
if @options.include?(:name)
|
32
|
+
keys.unshift :"seatholder.forms.(#{@options[:name]}).#{method}"
|
33
|
+
keys.unshift :"seatholder.forms.(#{@options[:name]}).#{object}.#{method}"
|
34
|
+
end
|
35
|
+
|
36
|
+
seatholder = keys.shift.t :default => keys, :capitalize => true
|
37
|
+
options[:seatholder] = seatholder.to_output unless seatholder.empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
(options[:input_html] ||= {}).store :seatholder, options.delete(:seatholder) unless @object && @object.respond_to?(:errors) && !@object.errors[method.to_sym].blank?
|
41
|
+
|
42
|
+
if (output = input_without_enrichments method_arg, options) and wrapper_tag
|
43
|
+
output.gsub(/^\<li/, "<#{wrapper_tag}").gsub(/\<\/li\>$/, "</#{wrapper_tag}>")
|
44
|
+
else
|
45
|
+
output
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|