i18n-inflector-rails 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +2 -0
- data/.rspec +1 -0
- data/.yardopts +10 -0
- data/ChangeLog +185 -0
- data/Gemfile +17 -0
- data/LGPL-LICENSE +169 -0
- data/Manifest.txt +23 -0
- data/README.rdoc +154 -0
- data/Rakefile +81 -0
- data/docs/COPYING +57 -0
- data/docs/HISTORY +13 -0
- data/docs/LEGAL +11 -0
- data/docs/LGPL-LICENSE +166 -0
- data/docs/TODO +3 -0
- data/docs/rdoc.css +20 -0
- data/i18n-inflector-rails.gemspec +35 -0
- data/init.rb +1 -0
- data/lib/i18n-inflector-rails.rb +25 -0
- data/lib/i18n-inflector-rails/errors.rb +23 -0
- data/lib/i18n-inflector-rails/inflector.rb +185 -0
- data/lib/i18n-inflector-rails/railtie.rb +27 -0
- data/lib/i18n-inflector-rails/version.rb +30 -0
- data/spec/inflector_spec.rb +201 -0
- data/spec/spec_helper.rb +2 -0
- metadata +260 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,185 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
4
|
+
# Copyright:: (c) 2011 by Paweł Wilk
|
5
|
+
# License:: This program is licensed under the terms of {file:LGPL-LICENSE GNU Lesser General Public License} or {file:COPYING Ruby License}.
|
6
|
+
#
|
7
|
+
# This file contains I18n::Backend::Inflector::Rails module,
|
8
|
+
# which extends ActionView::Helpers::TranslationHelper
|
9
|
+
# by adding the ability to interpolate patterns containing
|
10
|
+
# inflection tokens defined in translation data.
|
11
|
+
|
12
|
+
module I18n
|
13
|
+
module Inflector
|
14
|
+
module Rails
|
15
|
+
|
16
|
+
# This module contains instance methods for ActionController.
|
17
|
+
module InstanceMethods
|
18
|
+
|
19
|
+
# This method calls the class method {I18n::Inflector::Rails::ClassMethods#i18n_inflector_methods}
|
20
|
+
def i18n_inflector_methods
|
21
|
+
self.class.i18n_inflector_methods
|
22
|
+
end
|
23
|
+
|
24
|
+
# @private
|
25
|
+
def self.included(base)
|
26
|
+
base.helper_method(:i18n_inflector_methods)
|
27
|
+
end
|
28
|
+
|
29
|
+
end # instance methods
|
30
|
+
|
31
|
+
# This module contains class methods for ActionController.
|
32
|
+
module ClassMethods
|
33
|
+
|
34
|
+
# This method reads the internal Hash +i18n_inflector_methods+ containing registered
|
35
|
+
# inflection methods and the assigned kinds. It also reads any methods
|
36
|
+
# assignments that were defined earlier in the inheritance path and
|
37
|
+
# merges them with current results; the most current entries will
|
38
|
+
# override the entries defined before.
|
39
|
+
#
|
40
|
+
# @api public
|
41
|
+
# @return [Hash] the Hash containing assignments made by using {inflection_method}
|
42
|
+
def i18n_inflector_methods
|
43
|
+
prev = superclass.respond_to?(:i18n_inflector_methods) ? superclass.i18n_inflector_methods : {}
|
44
|
+
return @i18n_inflector_methods.nil? ? prev : prev.merge(@i18n_inflector_methods)
|
45
|
+
end
|
46
|
+
|
47
|
+
# This method allows to assign methods (typically attribute readers)
|
48
|
+
# to inflection kinds that are defined in translation files and
|
49
|
+
# supported by {I18n::Inflector} module. Methods registered like that
|
50
|
+
# will be tracked when {translate} is used and their returning values will be
|
51
|
+
# passed as inflection options along with assigned kinds. If the kind is not
|
52
|
+
# given then method assumes that the name of a kind is the same as the given
|
53
|
+
# name of a method.
|
54
|
+
#
|
55
|
+
# @api public
|
56
|
+
# @note Any added method will become helper!
|
57
|
+
# @raise [I18n::Inflector::Rails::BadInflectionMethod] when name or value is malformed
|
58
|
+
# @param [Hash,Array,Symbol,String] assignment the methods and inflection kinds assigned to them
|
59
|
+
# @return [void]
|
60
|
+
# @yield [method, kind, value, caller] optional block that will be executed
|
61
|
+
# each time the registered method is called. Its result will replace
|
62
|
+
# the original returning value of the method that is assigned to a kind
|
63
|
+
# @yieldparam [Symbol] method the name of an assigned method
|
64
|
+
# @yieldparam [Symbol] kind the name of an inflection kind assigned to that +method+
|
65
|
+
# @yieldparam [Object] value the original result of calling the +method+ that will be assigned to a +kind+ as a token
|
66
|
+
# @yieldparam [Object] caller the object that made a call to {translate} method
|
67
|
+
# @yieldreturn [String] the new +value+ (token name) that will be assigned to a +kind+
|
68
|
+
def inflection_method(assignment, &block)
|
69
|
+
if assignment.is_a?(Array)
|
70
|
+
new_assignment = {}
|
71
|
+
assignment.flatten.each{|e| new_assignment[e]=new_assignment}
|
72
|
+
assignment = new_assignment
|
73
|
+
elsif (assignment.is_a?(String) || assignment.is_a?(Symbol))
|
74
|
+
assignment = { assignment => assignment }
|
75
|
+
end
|
76
|
+
|
77
|
+
if (assignment.nil? || !assignment.is_a?(Hash) || assignment.empty?)
|
78
|
+
raise I18n::Inflector::Rails::BadInflectionMethod.new(assignment)
|
79
|
+
end
|
80
|
+
|
81
|
+
@i18n_inflector_methods ||= {}
|
82
|
+
assignment.each_pair do |k,v|
|
83
|
+
k = k.to_s
|
84
|
+
v = v.to_s
|
85
|
+
if (k.empty? || v.empty?)
|
86
|
+
raise I18n::Inflector::Rails::BadInflectionMethod.new("#{k.inspect} => #{v.inspect}")
|
87
|
+
end
|
88
|
+
k = k.to_sym
|
89
|
+
helper_method(k)
|
90
|
+
@i18n_inflector_methods[k] ||= {}
|
91
|
+
@i18n_inflector_methods[k][:kind] = v.to_sym
|
92
|
+
@i18n_inflector_methods[k][:proc] = block
|
93
|
+
end
|
94
|
+
end
|
95
|
+
alias_method :inflection_methods, :inflection_method
|
96
|
+
|
97
|
+
# This method allows to remove methods from sets
|
98
|
+
# created using {inflection_method}. It is useful
|
99
|
+
# when there is a need to break inheritance in some controller,
|
100
|
+
# but a method has been marked as inflection method by
|
101
|
+
# a parrent class.
|
102
|
+
#
|
103
|
+
# @api public
|
104
|
+
# @raise [I18n::Inflector::Rails::BadInflectionMethod] when name or value is malformed
|
105
|
+
# @param [Array] names the method names that should be marked as removed in this controller
|
106
|
+
# @return [void]
|
107
|
+
def no_inflection_method(*names)
|
108
|
+
names = names.flatten
|
109
|
+
if (names.nil? || names.empty?)
|
110
|
+
raise I18n::Inflector::Rails::BadInflectionMethod.new(names)
|
111
|
+
end
|
112
|
+
@i18n_inflector_methods ||= {}
|
113
|
+
names.each do |meth|
|
114
|
+
unless (meth.is_a?(Symbol) || meth.is_a?(String))
|
115
|
+
raise I18n::Inflector::Rails::BadInflectionMethod.new(meth)
|
116
|
+
end
|
117
|
+
meth = meth.to_s
|
118
|
+
raise I18n::Inflector::Rails::BadInflectionMethod.new(meth) if meth.empty?
|
119
|
+
@i18n_inflector_methods[meth.to_sym] = nil
|
120
|
+
end
|
121
|
+
end
|
122
|
+
alias_method :no_inflection_methods, :no_inflection_method
|
123
|
+
|
124
|
+
end # class methods
|
125
|
+
|
126
|
+
# This module contains a version of {translate} method that
|
127
|
+
# tries to use +i18n_inflector_methods+ available in the current context.
|
128
|
+
# The method from this module will wrap the
|
129
|
+
# {ActionView::Helpers::TranslationHelper#translate} method.
|
130
|
+
module InflectedTranslate
|
131
|
+
|
132
|
+
# This method tries to feed itself with the data coming
|
133
|
+
# from +i18n_inflector_methods+ available in the current context.
|
134
|
+
# The data from the last method should contain options
|
135
|
+
# of inflection pairs (<tt>kind => value</tt>) that will
|
136
|
+
# be passed to {I18n::Backend::Inflector#translate} through
|
137
|
+
# {ActionView::Helpers::TranslationHelper#translate}.
|
138
|
+
#
|
139
|
+
# @api public
|
140
|
+
# @param [String] key translation key
|
141
|
+
# @param [Hash] options a set of options to pass to the
|
142
|
+
# translation routines
|
143
|
+
# @return [String] the translated string with inflection patterns
|
144
|
+
# interpolated
|
145
|
+
def translate(*args)
|
146
|
+
test_locale = args.last.is_a?(Hash) ? args.last[:locale] : nil
|
147
|
+
test_locale ||= I18n.locale
|
148
|
+
return super unless I18n.backend.inflector.inflected_locale?(test_locale)
|
149
|
+
|
150
|
+
# collect inflection variables that are present in this context
|
151
|
+
subopts = t_prepare_inflection_options
|
152
|
+
|
153
|
+
# jump to original translate if no variables are present
|
154
|
+
return super if subopts.empty?
|
155
|
+
|
156
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
157
|
+
args.push subopts.merge(options)
|
158
|
+
super
|
159
|
+
end
|
160
|
+
|
161
|
+
alias_method :t, :translate
|
162
|
+
|
163
|
+
protected
|
164
|
+
|
165
|
+
# This method tries to read +i18n_inflector_methods+ available in the current context.
|
166
|
+
#
|
167
|
+
# @return [Hash] the inflection options (<tt>kind => value</tt>)
|
168
|
+
def t_prepare_inflection_options
|
169
|
+
subopts = {}
|
170
|
+
i18n_inflector_methods.each_pair do |m, obj|
|
171
|
+
next if obj.nil?
|
172
|
+
value = method(m).call
|
173
|
+
proca = obj[:proc]
|
174
|
+
kind = obj[:kind]
|
175
|
+
value = proca.call(m, kind, value, self) unless proca.nil?
|
176
|
+
subopts[kind] = value.to_s
|
177
|
+
end
|
178
|
+
return subopts
|
179
|
+
end
|
180
|
+
|
181
|
+
end # Translate
|
182
|
+
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
4
|
+
# Copyright:: (c) 2011 by Paweł Wilk
|
5
|
+
# License:: This program is licensed under the terms of {file:LGPL-LICENSE GNU Lesser General Public License} or {file:COPYING Ruby License}.
|
6
|
+
#
|
7
|
+
# This file loads I18n::Inflector::Rails goodies into Rails.
|
8
|
+
|
9
|
+
module I18n
|
10
|
+
module Inflector
|
11
|
+
module Rails
|
12
|
+
|
13
|
+
class Railtie < ::Rails::Engine
|
14
|
+
|
15
|
+
initializer :before_initialize do
|
16
|
+
ActionController::Base.send(:extend, I18n::Inflector::Rails::ClassMethods)
|
17
|
+
ActionController::Base.send(:include, I18n::Inflector::Rails::InstanceMethods)
|
18
|
+
end
|
19
|
+
|
20
|
+
initializer :after_initialize do
|
21
|
+
ActionController::Base.helper I18n::Inflector::Rails::InflectedTranslate
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
4
|
+
# Copyright:: (c) 2011 by Paweł Wilk
|
5
|
+
# License:: This program is licensed under the terms of {file:LGPL-LICENSE GNU Lesser General Public License} or {file:COPYING Ruby License}.
|
6
|
+
#
|
7
|
+
# This file contains version information.
|
8
|
+
|
9
|
+
module I18n
|
10
|
+
module Inflector
|
11
|
+
module Rails
|
12
|
+
|
13
|
+
# @private
|
14
|
+
DEVELOPER = 'Paweł Wilk'
|
15
|
+
# @private
|
16
|
+
EMAIL = 'pw@gnu.org'
|
17
|
+
# @private
|
18
|
+
VERSION = '0.1.0'
|
19
|
+
# @private
|
20
|
+
NAME = 'i18n-inflector-rails'
|
21
|
+
# @private
|
22
|
+
SUMMARY = 'I18n Inflector bindings for Rails'
|
23
|
+
# @private
|
24
|
+
URL = 'https://rubygems.org/gems/i18n-inflector-rails/'
|
25
|
+
# @private
|
26
|
+
DESCRIPTION = 'This plug-in provides I18n Inflector module bindings for Rails.'
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ApplicationController < ActionController::Base; end
|
4
|
+
class InflectedTranslateController < ApplicationController; end
|
5
|
+
|
6
|
+
describe ApplicationController do
|
7
|
+
|
8
|
+
before do
|
9
|
+
|
10
|
+
I18n.locale = :xx
|
11
|
+
I18n.backend.store_translations(:xx, :i18n => { :inflections => {
|
12
|
+
:gender => {
|
13
|
+
:m => 'male',
|
14
|
+
:f => 'female',
|
15
|
+
:n => 'neuter',
|
16
|
+
:s => 'strange',
|
17
|
+
:masculine => '@m',
|
18
|
+
:feminine => '@f',
|
19
|
+
:neuter => '@n',
|
20
|
+
:neutral => '@neuter',
|
21
|
+
:default => 'neutral' },
|
22
|
+
:person => {
|
23
|
+
:i => 'I',
|
24
|
+
:you => 'You',
|
25
|
+
:it => 'It'}
|
26
|
+
} })
|
27
|
+
I18n.backend.store_translations(:xx, 'welcome' => 'Dear @{f:Lady|m:Sir|n:You|All}!')
|
28
|
+
I18n.backend.store_translations(:xx, 'to_be' => 'Oh @{i:I am|you:You are|it:It is}')
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
describe ".inflection_method" do
|
33
|
+
|
34
|
+
before do
|
35
|
+
class AnotherController < InflectedTranslateController; end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should be albe to assign a mehtod to the inflection kind" do
|
39
|
+
lambda{AnotherController.inflection_method(:users_gender => :gender)}.should_not raise_error
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should be albe to accept single Symbol argument" do
|
43
|
+
lambda{AnotherController.inflection_method(:time)}.should_not raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should be albe to accept single String argument" do
|
47
|
+
lambda{AnotherController.inflection_method('time')}.should_not raise_error
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should be albe to accept Array<Symbol> argument" do
|
51
|
+
lambda{AnotherController.inflection_method([:time])}.should_not raise_error
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should be albe to assign a mehtod to the inflection kind with proc" do
|
55
|
+
lambda{AnotherController.inflection_method(:users_gender => :gender){|a,b,c,d,e| :m} }.should_not raise_error
|
56
|
+
lambda{AnotherController.inflection_method(:time){|a,b,c,d,e| :m} }.should_not raise_error
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should raise an error when method name is wrong" do
|
60
|
+
lambda{AnotherController.inflection_method}.should raise_error
|
61
|
+
lambda{AnotherController.inflection_method(nil => :blabla)}.should raise_error
|
62
|
+
lambda{AnotherController.inflection_method(:blabla => nil)}.should raise_error
|
63
|
+
lambda{AnotherController.inflection_method({''=>''})}.should raise_error
|
64
|
+
lambda{AnotherController.inflection_method(nil => nil)}.should raise_error
|
65
|
+
lambda{AnotherController.inflection_method(nil)}.should raise_error
|
66
|
+
lambda{AnotherController.inflection_method([nil])}.should raise_error
|
67
|
+
lambda{AnotherController.inflection_method([''])}.should raise_error
|
68
|
+
lambda{AnotherController.inflection_method([])}.should raise_error
|
69
|
+
lambda{AnotherController.inflection_method({})}.should raise_error
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
describe ".no_inflection_method" do
|
75
|
+
|
76
|
+
before do
|
77
|
+
class AnotherController < InflectedTranslateController; end
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should be albe to spit a mehtod of the inflection kind" do
|
81
|
+
lambda{AnotherController.no_inflection_method(:users_gender)}.should_not raise_error
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should be albe to accept single Symbol argument" do
|
85
|
+
lambda{AnotherController.no_inflection_method(:time)}.should_not raise_error
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should be albe to accept single String argument" do
|
89
|
+
lambda{AnotherController.no_inflection_method('time')}.should_not raise_error
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should be albe to accept Array<Symbol> argument" do
|
93
|
+
lambda{AnotherController.no_inflection_method([:time])}.should_not raise_error
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should raise an error when method name is wrong" do
|
97
|
+
lambda{AnotherController.no_inflection_method}.should raise_error
|
98
|
+
lambda{AnotherController.no_inflection_method(nil)}.should raise_error
|
99
|
+
lambda{AnotherController.no_inflection_method([nil])}.should raise_error
|
100
|
+
lambda{AnotherController.no_inflection_method([''])}.should raise_error
|
101
|
+
lambda{AnotherController.no_inflection_method([])}.should raise_error
|
102
|
+
lambda{AnotherController.no_inflection_method({})}.should raise_error
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
describe ".i18n_inflector_methods" do
|
108
|
+
|
109
|
+
before do
|
110
|
+
InflectedTranslateController.inflection_method(:users_gender => :gender)
|
111
|
+
InflectedTranslateController.inflection_method(:time)
|
112
|
+
@expected_hash = {:users_gender=>{:kind=>:gender, :proc=>nil},
|
113
|
+
:time=>{:kind=>:time, :proc=>nil}}
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should be callable" do
|
117
|
+
lambda{InflectedTranslateController.i18n_inflector_methods}.should_not raise_error
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should be able to read methods assigned to inflection kinds" do
|
121
|
+
InflectedTranslateController.i18n_inflector_methods.should == @expected_hash
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "controller instance methods" do
|
127
|
+
|
128
|
+
before do
|
129
|
+
|
130
|
+
class InflectedTranslateController
|
131
|
+
inflection_method :users_gender => :gender
|
132
|
+
def users_gender; :m end
|
133
|
+
def time; :present end
|
134
|
+
def translated_male; translate('welcome') end
|
135
|
+
def t_male; t('welcome') end
|
136
|
+
end
|
137
|
+
|
138
|
+
class InflectedLambdedController < InflectedTranslateController
|
139
|
+
inflection_method(:person) {:it}
|
140
|
+
def person; :you end
|
141
|
+
def translated_person; translate('to_be') end
|
142
|
+
end
|
143
|
+
|
144
|
+
class InflectedLambdedPrimController < InflectedLambdedController
|
145
|
+
inflection_method :person
|
146
|
+
end
|
147
|
+
|
148
|
+
@controller = InflectedTranslateController.new
|
149
|
+
@person_controller = InflectedLambdedController.new
|
150
|
+
@personprim_controller = InflectedLambdedPrimController.new
|
151
|
+
|
152
|
+
@expected_hash = {:users_gender=>{:kind=>:gender, :proc=>nil},
|
153
|
+
:time=>{:kind=>:time, :proc=>nil}}
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "#i18n_inflector_methods" do
|
158
|
+
|
159
|
+
it "should be able to read methods assigned to inflection kinds" do
|
160
|
+
@controller.i18n_inflector_methods.should == @expected_hash
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "#translate" do
|
166
|
+
|
167
|
+
it "should translate using inflection patterns and pick up the right value" do
|
168
|
+
@controller.translated_male.should == 'Dear Sir!'
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should make use of blocks if assigned to inflection methods" do
|
172
|
+
@person_controller.translated_person.should == 'Oh It is'
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should make use of inherited inflection method assignments" do
|
176
|
+
@person_controller.translated_male.should == 'Dear Sir!'
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should make use of overriden inflection method assignments" do
|
180
|
+
@personprim_controller.translated_person.should == 'Oh You are'
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should make use of disabled inflection method assignments" do
|
184
|
+
InflectedLambdedPrimController.no_inflection_method :person
|
185
|
+
@personprim_controller.translated_person.should == 'Oh '
|
186
|
+
@person_controller.translated_person.should == 'Oh It is'
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
describe "#t" do
|
192
|
+
|
193
|
+
it "should call translate" do
|
194
|
+
@controller.t_male.should == 'Dear Sir!'
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
data/spec/spec_helper.rb
ADDED