i18n_scopes 0.0.1
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 +17 -0
- data/.rspec +2 -0
- data/Gemfile +10 -0
- data/LICENSE +22 -0
- data/README.md +62 -0
- data/Rakefile +2 -0
- data/i18n_scopes.gemspec +18 -0
- data/lib/i18n_scopes.rb +9 -0
- data/lib/i18n_scopes/configuration.rb +59 -0
- data/lib/i18n_scopes/scope.rb +43 -0
- data/lib/i18n_scopes/translation_helper.rb +147 -0
- data/lib/i18n_scopes/translation_methods.rb +44 -0
- data/lib/i18n_scopes/version.rb +3 -0
- data/spec/configuration_spec.rb +21 -0
- data/spec/example_classes/respondable.rb +7 -0
- data/spec/example_classes/scope_t_with_path.rb +36 -0
- data/spec/example_classes/scope_t_with_path_in_module.rb +24 -0
- data/spec/example_classes/should_define_scope.rb +5 -0
- data/spec/example_classes/should_have_attached_scoped_t.rb +3 -0
- data/spec/include_scope_spec.rb +19 -0
- data/spec/locales/en.yml +18 -0
- data/spec/scope_spec.rb +20 -0
- data/spec/should_define_scope_in_module_spec.rb +8 -0
- data/spec/should_define_scope_spec.rb +16 -0
- data/spec/spec_helper.rb +18 -0
- metadata +99 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 TODO: Write your name
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# I18nScopes
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
Add this line to your application's Gemfile:
|
6
|
+
|
7
|
+
gem 'i18n_scopes'
|
8
|
+
|
9
|
+
And then execute:
|
10
|
+
|
11
|
+
$ bundle
|
12
|
+
|
13
|
+
Or install it yourself as:
|
14
|
+
|
15
|
+
$ gem install i18n_scopes
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
### Configuration
|
20
|
+
|
21
|
+
I18nScopes.configure do |config|
|
22
|
+
config.plural_classes = false
|
23
|
+
config.strip_controller_suffix = true
|
24
|
+
config.attach_to ActionController::Base
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
### In your class (for example Controller)
|
31
|
+
|
32
|
+
class Local::ExampleController < ActionController::Base
|
33
|
+
i18n_scope [:class_name, :translation, :action_name], :strip_controller_suffix => true, :plural_class => false
|
34
|
+
|
35
|
+
def index
|
36
|
+
@post = Post.new
|
37
|
+
self.examples
|
38
|
+
end
|
39
|
+
|
40
|
+
def examples
|
41
|
+
# the scoped_t method will inherit the path from the i18n_scope method
|
42
|
+
scoped_t :name # => [:example, :translation, :index, :name]
|
43
|
+
|
44
|
+
# the path can be overwritten with an option
|
45
|
+
scoped_t :name, :path => [:elsewhere] # => [:elsewhere, :name]
|
46
|
+
|
47
|
+
# the path can be extended through the :path_extension options, it'll be attached to the end of path
|
48
|
+
scoped_t :name, :path_extension => [:flash], # => [:example, :translation, :index, :flash, :name]
|
49
|
+
|
50
|
+
# it's also possible to use local methods as path, in this example :modules_with_extension will be called, note that
|
51
|
+
scoped_t :name, :path_extension => [:modules_with_extension] # => [:example, :translation, :index, :local_modules, :name]
|
52
|
+
|
53
|
+
# in this example, the post object will be given as argument, @post will respond to :post_scope and returns :normal
|
54
|
+
scope_t :name, :path_extension => [:post_scope], :respondable => [@post] # => [:example, :translation, :index, :normal, :name]
|
55
|
+
end
|
56
|
+
|
57
|
+
def modules_with_extension(modules)
|
58
|
+
"#{modules}_modules"
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
data/Rakefile
ADDED
data/i18n_scopes.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/i18n_scopes/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["menostos"]
|
6
|
+
gem.email = ["menostos@gmail.com"]
|
7
|
+
gem.description = %q{A gem for adding dynamic scopes to classes}
|
8
|
+
gem.summary = %q{This gem will attach a scoped_t method to your class. The scope will be configureable in your class or globally.}
|
9
|
+
gem.homepage = "http://github.com/menostos/i18n_scopes"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "i18n_scopes"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = I18nScopes::VERSION
|
17
|
+
gem.add_development_dependency 'rspec'
|
18
|
+
end
|
data/lib/i18n_scopes.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
|
2
|
+
require 'i18n_scopes/scope'
|
3
|
+
require 'i18n_scopes/configuration'
|
4
|
+
require 'i18n_scopes/translation_methods'
|
5
|
+
require 'i18n_scopes/translation_helper'
|
6
|
+
require 'active_support/concern'
|
7
|
+
require 'active_support/core_ext/string/inflections'
|
8
|
+
|
9
|
+
Object.send :include, I18nScopes::Scope
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# extend the I18nScopes module to support configuration
|
2
|
+
# see I18nScopes::Configuration
|
3
|
+
module I18nScopes
|
4
|
+
|
5
|
+
# use this method to configure I18nScopes
|
6
|
+
#
|
7
|
+
# I18nScopes.configure do |config|
|
8
|
+
# config.plural_classes = false
|
9
|
+
# config.strip_controller_suffix = true
|
10
|
+
# config.attach_to ActionController::Base, YourCustomClass, EtcClass
|
11
|
+
# end
|
12
|
+
def self.configure # :yield: config
|
13
|
+
yield self.configuration
|
14
|
+
end
|
15
|
+
|
16
|
+
# returns the Configuration
|
17
|
+
def self.configuration
|
18
|
+
@configuration ||= Configuration.new
|
19
|
+
end
|
20
|
+
|
21
|
+
# this class is used to hold the global configuration made for I18nScopes
|
22
|
+
class Configuration
|
23
|
+
|
24
|
+
attr_accessor :plural_classes
|
25
|
+
attr_accessor :strip_controller_suffix
|
26
|
+
|
27
|
+
# Attach the I18nScope methods to the given class or classes
|
28
|
+
#
|
29
|
+
# === Params:
|
30
|
+
# * +klasses+:: +Class+ one or more Class the include the I18nScopes methods
|
31
|
+
#
|
32
|
+
# I18nScopes.configuration.attach_to ActionController::Base, YourCustomClass, EtcClass
|
33
|
+
def attach_to(*klasses)
|
34
|
+
klasses.each do |klass|
|
35
|
+
klass.send :include, I18nScopes::Scope
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# accessor for plural_classes options
|
40
|
+
def plural_classes
|
41
|
+
@plural_classes ||= false
|
42
|
+
end
|
43
|
+
|
44
|
+
# accessor for strip_controller_suffix options
|
45
|
+
def strip_controller_suffix
|
46
|
+
@strip_controller_suffix ||= true
|
47
|
+
end
|
48
|
+
|
49
|
+
# returns the Configuration as option Hash
|
50
|
+
def as_options
|
51
|
+
{
|
52
|
+
:plural_classes => self.plural_classes,
|
53
|
+
:strip_controller_suffix => self.strip_controller_suffix
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module I18nScopes
|
2
|
+
|
3
|
+
# This module can be included to get the i18n_scope method on every class
|
4
|
+
#
|
5
|
+
# this can also be achieved using the Configuration#attach_to method from the Configuration
|
6
|
+
#
|
7
|
+
# === Usage:
|
8
|
+
#
|
9
|
+
# class Example
|
10
|
+
# include I18nScopes::Scope
|
11
|
+
# end
|
12
|
+
module Scope
|
13
|
+
|
14
|
+
extend ActiveSupport::Concern
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
|
18
|
+
attr_accessor :i18n_scope_helper
|
19
|
+
|
20
|
+
# Use this method to configure how the scope will be built when using translations
|
21
|
+
# === Params:
|
22
|
+
# * +path+: Either a single String or Symbol, or an Array of Symbols and Strings
|
23
|
+
# * +options+: options to be used within this class, they will overwrite the configuration made in Configuration
|
24
|
+
# * :plural_class: if the class name should be pluralized or singularized
|
25
|
+
# * :strip_controller_suffix: if the _controller suffix of classes should be stripped or not
|
26
|
+
#
|
27
|
+
# == Usage:
|
28
|
+
# i18n_scope [:modules, :class_name, :action_name, :custom_value, "static_prefix"], :plural_class => true, :strip_controller_suffix => true
|
29
|
+
#
|
30
|
+
# with a Tweets::PostsController, the action index and a custom_value method that returns a_value this will led to the following scope:
|
31
|
+
#
|
32
|
+
# [:tweets, :posts, :index, :a_value, "static_prefix"]
|
33
|
+
def i18n_scope(path, options = {})
|
34
|
+
path = [path] unless path.is_a?(Array)
|
35
|
+
self.i18n_scope_helper = I18nScopes::TranslationHelper.new(path, options)
|
36
|
+
self.send :include, I18nScopes::TranslationMethods
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module I18nScopes
|
2
|
+
|
3
|
+
# this class provides helper methods to determine the actual scope in your class
|
4
|
+
class TranslationHelper
|
5
|
+
|
6
|
+
CONTROLLER_SUFFIX = "_controller"
|
7
|
+
|
8
|
+
attr_accessor :path
|
9
|
+
attr_accessor :options
|
10
|
+
|
11
|
+
# === Params:
|
12
|
+
# * +path+: the path from i18n_scope
|
13
|
+
# * +options+ the options from i18n_scope
|
14
|
+
def initialize(path, options = {})
|
15
|
+
self.path = path
|
16
|
+
self.options = I18nScopes.configuration.as_options.merge(options)
|
17
|
+
end
|
18
|
+
|
19
|
+
# === Params:
|
20
|
+
# * +object+: the object which is doing a translation
|
21
|
+
# * +options+: additional options for this translation
|
22
|
+
# * +parameter_matchings+: a Hash providing arguments to custom methods
|
23
|
+
def scope_from_path(object, options, parameter_matchings)
|
24
|
+
scope = []
|
25
|
+
custom_path = options.delete(:path) || self.path
|
26
|
+
custom_path += options.delete(:path_extension) || []
|
27
|
+
respondables = [object]
|
28
|
+
respondables += options.delete(:respondable) if options.include?(:respondable)
|
29
|
+
respondables << self # add self at last
|
30
|
+
custom_path.each do |path_name|
|
31
|
+
if path_name.is_a?(Symbol)
|
32
|
+
respondable = respondables.find{ |respondable| respondable.respond_to?(path_name) } # find a respondable which responds_to path_name
|
33
|
+
if respondable
|
34
|
+
result = value_from_method_call(respondable, respondables, path_name, parameter_matchings) # call the path_name method on the respondable
|
35
|
+
if result.is_a?(Array)
|
36
|
+
scope += result # add all entries of an array
|
37
|
+
else
|
38
|
+
scope << result
|
39
|
+
end
|
40
|
+
else
|
41
|
+
scope << path_name # no object is respondable for this path_name, so just add the symbol to the scope
|
42
|
+
end
|
43
|
+
elsif path_name.is_a?(String)
|
44
|
+
scope << path_name
|
45
|
+
end
|
46
|
+
end
|
47
|
+
return scope
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
# returns the value from method path ond object using parameter_matchings as arguments
|
52
|
+
#
|
53
|
+
# === Params:
|
54
|
+
# * +object+: the object to call the method on
|
55
|
+
# * +respondables+: the objects on which arguments will be searched on
|
56
|
+
# * +method_name+: the method name to call
|
57
|
+
# * +parameter_matchings+: additional parameter_matchings as a Hash
|
58
|
+
def value_from_method_call(object, respondables, method_name, parameter_matchings)
|
59
|
+
method = object.class.instance_method(method_name)
|
60
|
+
if method.arity == 0
|
61
|
+
return object.send(method_name)
|
62
|
+
else
|
63
|
+
return object.send(method_name, *self.compute_arguments_for(respondables, method, parameter_matchings))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# this method will compute all required (and optional) arguments for method on object
|
68
|
+
#
|
69
|
+
# === Params:
|
70
|
+
# * +objects+: the objects on which the arguments should be collected
|
71
|
+
# * +method+: the method on which the arguments should be determined
|
72
|
+
# * +parameter_matchings+: additional paramteters_matchings as a Hash
|
73
|
+
def compute_arguments_for(objects, method, parameter_matchings)
|
74
|
+
args = []
|
75
|
+
parameters = method.parameters
|
76
|
+
parameters.each do |type, name|
|
77
|
+
if parameter_matchings.include?(name)
|
78
|
+
args << parameter_matchings[name]
|
79
|
+
elsif object = objects.find{|o| o.respond_to?(name) }
|
80
|
+
if object.class.instance_method(name).arity == 0
|
81
|
+
args << object.send(name)
|
82
|
+
else
|
83
|
+
method = object.class.instance_method(name)
|
84
|
+
args << object.send(name, *self.compute_arguments_for(objects, method, parameter_matchings))
|
85
|
+
end
|
86
|
+
elsif type == :req
|
87
|
+
raise "Could not find parameter #{name} for method #{method.name}"
|
88
|
+
else
|
89
|
+
break # break if type is :opt and we couldn't find a value
|
90
|
+
end
|
91
|
+
end
|
92
|
+
return args
|
93
|
+
end
|
94
|
+
|
95
|
+
# this method will return all modules in a array, each module will be underscored
|
96
|
+
#
|
97
|
+
# === Params:
|
98
|
+
# * +klass+: the klass of which the modules should be used
|
99
|
+
def modules(klass)
|
100
|
+
@modules ||= begin
|
101
|
+
modules = ActiveSupport::Inflector.deconstantize(klass.name)
|
102
|
+
modules = ActiveSupport::Inflector.underscore(modules)
|
103
|
+
modules.split("::")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# this method will return a underscored class_name
|
108
|
+
#
|
109
|
+
# Note: plural_class and strip_controller_suffix will be used here
|
110
|
+
#
|
111
|
+
# === Params:
|
112
|
+
# * +klass+: the class on which the name should be get
|
113
|
+
# * +options+: options like plural_class and strip_controller_suffix
|
114
|
+
def class_name(klass, options = {})
|
115
|
+
@class_name ||= begin
|
116
|
+
class_name_options = self.options.merge(options)
|
117
|
+
class_name = ActiveSupport::Inflector.demodulize(klass.name)
|
118
|
+
class_name = ActiveSupport::Inflector.underscore(class_name)
|
119
|
+
class_name = class_name[0, class_name.length - CONTROLLER_SUFFIX.length] if class_name_options[:strip_controller_suffix] && class_name.end_with?(CONTROLLER_SUFFIX)
|
120
|
+
if class_name_options[:plural_class]
|
121
|
+
ActiveSupport::Inflector.pluralize(class_name)
|
122
|
+
else
|
123
|
+
ActiveSupport::Inflector.singularize(class_name)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# returns the method name of the original caller
|
129
|
+
def method_name
|
130
|
+
found_scoped_t_at = nil
|
131
|
+
caller.each_with_index do |call, index|
|
132
|
+
if call.include?("scoped_t")
|
133
|
+
found_scoped_t_at = index
|
134
|
+
break
|
135
|
+
end
|
136
|
+
end
|
137
|
+
if found_scoped_t_at && call = caller[found_scoped_t_at + 1]
|
138
|
+
if /^(.+?):(\d+)(?::in `(.*)')?/ =~ call
|
139
|
+
return Regexp.last_match[3]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
raise "Failed to get method_name"
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module I18nScopes
|
2
|
+
|
3
|
+
module TranslationMethods
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
protected
|
7
|
+
# translates the given key under the configured scope
|
8
|
+
#
|
9
|
+
# === Params:
|
10
|
+
# * +key+: the translation key to lookup
|
11
|
+
# * +options+:
|
12
|
+
# * +path+: +Array+ the path to be overwritten
|
13
|
+
# * +path_extension+: +Array+ an additional path to the one configued using Scope::ClassMethods#i18n_scope (will be attached to the end)
|
14
|
+
# * +respondable+: an array of objects on which the methods should be looked up
|
15
|
+
# * +parameter_matchings+: a hash containing arguments for the dynamic method calls
|
16
|
+
def scoped_t(*args)
|
17
|
+
options = args.extract_options!
|
18
|
+
|
19
|
+
additional_parameters = if self.respond_to?(:i18n_parameter_matchings)
|
20
|
+
self.i18n_parameter_matchings
|
21
|
+
else
|
22
|
+
options.delete(:parameter_matchings) || {}
|
23
|
+
end
|
24
|
+
|
25
|
+
parameter_matchings = {
|
26
|
+
:klass => self.class,
|
27
|
+
:object => self,
|
28
|
+
:options => options,
|
29
|
+
}.merge(additional_parameters)
|
30
|
+
|
31
|
+
scope = self.i18n_scope_helper.scope_from_path(self, options, parameter_matchings)
|
32
|
+
|
33
|
+
scope += options[:scope] if options.include?(:scope)
|
34
|
+
return I18n.translate *args, options.merge(:scope => scope)
|
35
|
+
end
|
36
|
+
|
37
|
+
# retusn the i18n_scope_helper instance of TranslationHelper
|
38
|
+
def i18n_scope_helper
|
39
|
+
return self.class.i18n_scope_helper
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'example_classes/should_have_attached_scoped_t'
|
3
|
+
|
4
|
+
describe I18nScopes::Configuration do
|
5
|
+
I18nScopes.configure do |config|
|
6
|
+
config.plural_classes = true
|
7
|
+
config.strip_controller_suffix = true
|
8
|
+
config.attach_to ShouldHaveAttachedScopedT
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:configuration) { I18nScopes.configuration }
|
12
|
+
subject { configuration }
|
13
|
+
|
14
|
+
its(:plural_classes) { should be_true }
|
15
|
+
its(:strip_controller_suffix) { should be_true }
|
16
|
+
|
17
|
+
it 'should attach i18n_scope to ShouldHaveAttachedScopedT' do
|
18
|
+
ShouldHaveAttachedScopedT.should respond_to(:i18n_scope)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class ScopeTWithPath
|
2
|
+
|
3
|
+
i18n_scope ["static_prefix", :class_prefix, :with_a_parameter, :class_name]
|
4
|
+
|
5
|
+
def translate
|
6
|
+
scoped_t(:name)
|
7
|
+
end
|
8
|
+
|
9
|
+
def translate_local
|
10
|
+
scoped_t(:name, :path => [:overwritten, :locally])
|
11
|
+
end
|
12
|
+
|
13
|
+
def translate_path_extension
|
14
|
+
scoped_t(:name, :path_extension => ["extension"])
|
15
|
+
end
|
16
|
+
|
17
|
+
def translate_with_respondable
|
18
|
+
scoped_t(:name, :path_extension => [:type], :respondable => [Respondable.new])
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
def class_prefix
|
23
|
+
:some_prefix_from_local_class
|
24
|
+
end
|
25
|
+
|
26
|
+
def with_a_parameter(the_parameter)
|
27
|
+
:"with_#{the_parameter}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def i18n_parameter_matchings
|
31
|
+
{
|
32
|
+
:the_parameter => :custom_value
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module SomeModule
|
2
|
+
class ScopeTWithPathInModule
|
3
|
+
|
4
|
+
i18n_scope [:modules, :local, :class_name]
|
5
|
+
|
6
|
+
def translate
|
7
|
+
scoped_t(:name)
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
def local(overwriteable)
|
12
|
+
:"prefix_#{overwriteable}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def overwriteable
|
16
|
+
:suffix
|
17
|
+
end
|
18
|
+
|
19
|
+
def module_with_ext(modules)
|
20
|
+
"moddd_#{modules}"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'example_classes/should_have_attached_scoped_t'
|
4
|
+
|
5
|
+
# Testing I18nScopes::Scope
|
6
|
+
describe ShouldHaveAttachedScopedT do
|
7
|
+
|
8
|
+
I18nScopes.configuration.attach_to(ShouldHaveAttachedScopedT)
|
9
|
+
subject { ShouldHaveAttachedScopedT }
|
10
|
+
|
11
|
+
it 'should respond to i18n_scope_helper' do
|
12
|
+
subject.should respond_to(:i18n_scope_helper)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should respond to i18n_scope' do
|
16
|
+
subject.should respond_to(:i18n_scope)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/spec/locales/en.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
en:
|
2
|
+
static_prefix:
|
3
|
+
some_prefix_from_local_class:
|
4
|
+
with_custom_value:
|
5
|
+
scope_t_with_path:
|
6
|
+
name: ScopeTWithPathTranslationFromFile
|
7
|
+
extension:
|
8
|
+
name: ScopeTWithPathPathExtension
|
9
|
+
normal:
|
10
|
+
name: ScopeTWithPathAndRespondable
|
11
|
+
|
12
|
+
some_module:
|
13
|
+
prefix_suffix:
|
14
|
+
scope_t_with_path_in_module:
|
15
|
+
name: ScopeTWithPathTranslationAndModule
|
16
|
+
overwritten:
|
17
|
+
locally:
|
18
|
+
name: ScopeTWithPathLocallyOverwritten
|
data/spec/scope_spec.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'example_classes/should_define_scope'
|
3
|
+
|
4
|
+
# Testing I18nScopes::Scope
|
5
|
+
describe ShouldDefineScope do
|
6
|
+
I18nScopes.configuration.attach_to(ShouldDefineScope)
|
7
|
+
let(:should_define_scope) { ShouldDefineScope.new }
|
8
|
+
subject { should_define_scope }
|
9
|
+
|
10
|
+
it 'should return I18nScopes::TranslationHelper for i18n_scope_helper' do
|
11
|
+
ShouldDefineScope.i18n_scope_helper.should be_instance_of(I18nScopes::TranslationHelper)
|
12
|
+
end
|
13
|
+
|
14
|
+
[:scoped_t, :i18n_scope_helper,].each do |method|
|
15
|
+
it "should respond to #{method}" do
|
16
|
+
should_define_scope.should respond_to(method)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'example_classes/scope_t_with_path'
|
3
|
+
require 'example_classes/respondable'
|
4
|
+
|
5
|
+
describe ScopeTWithPath do
|
6
|
+
|
7
|
+
|
8
|
+
its(:translate) { should == "ScopeTWithPathTranslationFromFile"}
|
9
|
+
|
10
|
+
its(:translate_local) { should == "ScopeTWithPathLocallyOverwritten"}
|
11
|
+
|
12
|
+
its(:translate_path_extension) { should == "ScopeTWithPathPathExtension" }
|
13
|
+
|
14
|
+
its(:translate_with_respondable) { should == "ScopeTWithPathAndRespondable" }
|
15
|
+
|
16
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require 'i18n'
|
5
|
+
|
6
|
+
require 'active_support/concern'
|
7
|
+
require 'active_support/core_ext/string/inflections'
|
8
|
+
|
9
|
+
require 'i18n_scopes'
|
10
|
+
|
11
|
+
I18n.load_path << File.join(File.dirname(__FILE__), "locales", "en.yml")
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
15
|
+
config.run_all_when_everything_filtered = true
|
16
|
+
config.filter_run :focus
|
17
|
+
config.order = 'random'
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: i18n_scopes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- menostos
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: A gem for adding dynamic scopes to classes
|
31
|
+
email:
|
32
|
+
- menostos@gmail.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- .gitignore
|
38
|
+
- .rspec
|
39
|
+
- Gemfile
|
40
|
+
- LICENSE
|
41
|
+
- README.md
|
42
|
+
- Rakefile
|
43
|
+
- i18n_scopes.gemspec
|
44
|
+
- lib/i18n_scopes.rb
|
45
|
+
- lib/i18n_scopes/configuration.rb
|
46
|
+
- lib/i18n_scopes/scope.rb
|
47
|
+
- lib/i18n_scopes/translation_helper.rb
|
48
|
+
- lib/i18n_scopes/translation_methods.rb
|
49
|
+
- lib/i18n_scopes/version.rb
|
50
|
+
- spec/configuration_spec.rb
|
51
|
+
- spec/example_classes/respondable.rb
|
52
|
+
- spec/example_classes/scope_t_with_path.rb
|
53
|
+
- spec/example_classes/scope_t_with_path_in_module.rb
|
54
|
+
- spec/example_classes/should_define_scope.rb
|
55
|
+
- spec/example_classes/should_have_attached_scoped_t.rb
|
56
|
+
- spec/include_scope_spec.rb
|
57
|
+
- spec/locales/en.yml
|
58
|
+
- spec/scope_spec.rb
|
59
|
+
- spec/should_define_scope_in_module_spec.rb
|
60
|
+
- spec/should_define_scope_spec.rb
|
61
|
+
- spec/spec_helper.rb
|
62
|
+
homepage: http://github.com/menostos/i18n_scopes
|
63
|
+
licenses: []
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
requirements: []
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 1.8.24
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: This gem will attach a scoped_t method to your class. The scope will be configureable
|
86
|
+
in your class or globally.
|
87
|
+
test_files:
|
88
|
+
- spec/configuration_spec.rb
|
89
|
+
- spec/example_classes/respondable.rb
|
90
|
+
- spec/example_classes/scope_t_with_path.rb
|
91
|
+
- spec/example_classes/scope_t_with_path_in_module.rb
|
92
|
+
- spec/example_classes/should_define_scope.rb
|
93
|
+
- spec/example_classes/should_have_attached_scoped_t.rb
|
94
|
+
- spec/include_scope_spec.rb
|
95
|
+
- spec/locales/en.yml
|
96
|
+
- spec/scope_spec.rb
|
97
|
+
- spec/should_define_scope_in_module_spec.rb
|
98
|
+
- spec/should_define_scope_spec.rb
|
99
|
+
- spec/spec_helper.rb
|