i18n_accessor 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # v0.1.0 (2015-09-30)
2
+
3
+ * initial gem release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in i18n_accessor.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Critical Juncture, LLC
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,179 @@
1
+ # I18nAccessor
2
+
3
+ I18nAccessor uses a little metaprogramming to provide some syntactic sugar that
4
+ will help clean up your views when using I18n to display static properties on an
5
+ object.
6
+
7
+ I18nAccessor is especially useful in combination with ActiveHash where you now
8
+ only need an `:identifier` attribute and can remove all other string based
9
+ values from the data array.
10
+
11
+ See Usage and Examples sections below.
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'i18n_accessor'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install i18n_accessor
28
+
29
+ ## Usage
30
+ Add `i18n_accessor` to your model as follows: `i18n_accessor :accessor`
31
+
32
+ This will look up the corresponding translation as follows:
33
+ ```yml
34
+ # config locales/en.yml, etc
35
+ model_name:
36
+ accessor: 'your string'
37
+ ```
38
+
39
+ I18nAccessor` also accepts a second `:scope` param as follows:
40
+ `i18n_accessor :accessor, scope: 'short'`
41
+
42
+ This will look up the corresponding translation as follows:
43
+ ```yml
44
+ # config/locales/en.yml, etc
45
+ model_name:
46
+ accessor:
47
+ short: 'your string'
48
+ ```
49
+
50
+ Often however when using `:scope` you'll have want to have more than one
51
+ accessor for the same key. In these cases you should also pass the `:key`
52
+ parameter:
53
+
54
+ ```ruby
55
+ # app/models/product.rb
56
+ i18n_accessor :short_category, key: "category", scope: "short"
57
+ i18n_accessor :long_category, key: "category", scope: "long"
58
+
59
+ # config/locales/en.yml
60
+ model_name:
61
+ key:
62
+ short: 'your string'
63
+ long: 'your longer, more verbose string'
64
+ ```
65
+
66
+ Scope can be any arbitrarily long string that you would use with the
67
+ I18n#translate method.
68
+
69
+ Scope is useful when you want to defined multiple accessors for the same key.
70
+
71
+ ## Examples
72
+
73
+ ### Simple
74
+ Simple usage is great for wrapping I18n strings in a method.
75
+
76
+ For example:
77
+
78
+ ```ruby
79
+ # app/models/product.rb
80
+ class Product
81
+ i18n_accessor :name
82
+ end
83
+
84
+ # config/locales/en.yml
85
+ product:
86
+ name: 'Product'
87
+
88
+ # app/views/products/show.html.erb
89
+ # you get:
90
+ <%= @product.name %>
91
+
92
+ # rather than:
93
+ <%= I18n.t('product.name') %>
94
+ ```
95
+
96
+ ### ActiveHash
97
+ When used with ActiveHash it allows you to remove all strings from your
98
+ data array and making it less verbose while also giving you get the added
99
+ benefit of the I18n translation layer.
100
+
101
+ When I18nAccessor detects your model inherits from ActiveHash::Base it assumes
102
+ that you have an `:identifer` key and uses the value of this to do the i18n
103
+ lookup.
104
+
105
+ A typical entry in an ActiveHash data array might look like:
106
+ ```ruby
107
+ # app/model/grade.rb
108
+ ...
109
+ {id: 7, identifier: :first, long_name: 'First grade', short_name: '1st'},
110
+ ...
111
+ ```
112
+
113
+ With I18nAccessor:
114
+
115
+ ```ruby
116
+ # app/models/grade.rb
117
+ class Grade < ActiveHash::Base
118
+ include ActiveHashI18n
119
+ i18n_accessor :short_name, scope: 'short'
120
+ i18n_accessor :long_name, scope: 'long'
121
+
122
+ self.data = [
123
+ {id: 0, identifier: :kindergarten},
124
+ {id: 1, identifier: :first},
125
+ {id: 2, identifier: :second}
126
+ #...
127
+ ]
128
+ end
129
+
130
+ # config/locales/en.yml
131
+ grade:
132
+ kindergarten:
133
+ long: Kindergarten
134
+ short: Kindergarten
135
+ first:
136
+ long: First grade
137
+ short: 1st Grade
138
+ second:
139
+ long: Second grade
140
+ short: 2nd Grade
141
+
142
+ # app/views/grades/show.html.erb
143
+ <%= @grade.short_name %>
144
+ <%= @grade.long_name %>
145
+ ```
146
+
147
+ Without I18nAccessor you'd end up with each element of your active_hash data
148
+ array needing a short_name and long_name key and value
149
+ (eg. `short_name: I18n.t('grade.kindergarten.short')`).
150
+
151
+ Note: when using `:scope` with ActiveHash you don't specify a `:key`
152
+ when creating multiple accessors. This is because the key is inferred from the
153
+ `:identifier` property on the data item.
154
+
155
+ When using I18nAccessor on an ActiveHash based class in order to create an
156
+ accessor that isn't based on the currently instantiated object you'll need to
157
+ pass the `:key` argument. This allows you to also make the use of simple case
158
+ outlined above.
159
+
160
+ ```ruby
161
+ # app/models/grade.rb
162
+ i18n_accessor :name, key: 'name'
163
+
164
+ # config/locales/en.yml
165
+ grade:
166
+ name: Grade
167
+ kindergarten:
168
+ long: Kindergarten
169
+ short: Kindergarten
170
+ ...
171
+ ```
172
+
173
+ ## Contributing
174
+
175
+ 1. Fork it ( https://github.com/[my-github-username]/i18n_accessor/fork )
176
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
177
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
178
+ 4. Push to the branch (`git push origin my-new-feature`)
179
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'i18n_accessor/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "i18n_accessor"
8
+ spec.version = I18nAccessor::VERSION
9
+ spec.authors = ["Peregrinator"]
10
+ spec.email = ["bob.burbach@gmail.com"]
11
+ spec.summary = "Makes keys in your I18N files accessible as methods."
12
+ spec.description = "see README"
13
+ spec.homepage = "http://github.com/criticaljuncture/i18n_accessor"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "activesupport", ">= 3.0.0"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.7"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec", ">= 3.3.0"
26
+ spec.add_development_dependency "active_hash", '~> 1.4.0'
27
+ end
@@ -0,0 +1,36 @@
1
+ require "i18n_accessor/version"
2
+ require 'active_support/core_ext/string/inflections'
3
+
4
+ module I18nAccessor
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def i18n_accessor(accessor_name, options={})
11
+ scope = options.fetch(:scope) { nil }
12
+ key = options.fetch(:key) { nil }
13
+
14
+ class_name = self.name.underscore
15
+ is_active_hash = defined?(ActiveHash::Base) && self.ancestors.include?(ActiveHash::Base)
16
+
17
+ define_method accessor_name do
18
+ unless key
19
+ key = if is_active_hash
20
+ self.identifier
21
+ else
22
+ accessor_name
23
+ end
24
+ end
25
+
26
+ i18n_path = [
27
+ class_name,
28
+ key,
29
+ scope
30
+ ].compact.join('.')
31
+
32
+ I18n.t("#{i18n_path}")
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module I18nAccessor
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,18 @@
1
+ en:
2
+ product:
3
+ name: Automobile
4
+ category:
5
+ short: SUV
6
+ long: Sports Utility Vehicle
7
+
8
+ grade:
9
+ name: Grade
10
+ kindergarten:
11
+ long: Kindergarten
12
+ short: K
13
+ first:
14
+ long: First grade
15
+ short: 1st
16
+ second:
17
+ long: Second grade
18
+ short: 2nd
@@ -0,0 +1,64 @@
1
+ require 'active_hash'
2
+ require 'i18n_accessor'
3
+
4
+ class Grade < ActiveHash::Base
5
+ include I18nAccessor
6
+
7
+ i18n_accessor :name, key: 'name'
8
+
9
+ i18n_accessor :long_abbreviation, scope: 'long'
10
+ i18n_accessor :short_abbreviation, scope: 'short'
11
+
12
+ self.data = [
13
+ {id: 0, identifier: :kindergarten},
14
+ {id: 1, identifier: :first},
15
+ {id: 2, identifier: :second}
16
+ ]
17
+ end
18
+
19
+ class Product
20
+ include I18nAccessor
21
+
22
+ i18n_accessor :name
23
+ i18n_accessor :short_category, key: "category", scope: "short"
24
+ i18n_accessor :long_category, key: "category", scope: "long"
25
+ end
26
+
27
+ describe "I18nAccessor" do
28
+ before(:all) do
29
+ I18n.load_path = ["spec/fixtures/locales/en.yml"]
30
+ I18n.locale = 'en'
31
+ end
32
+
33
+ describe "#i18n_accessor" do
34
+ let(:product) { Product.new }
35
+
36
+ it "returns the proper i18n string for a simple usage" do
37
+ expect(product.name).to eql( I18n.t('product.name') )
38
+ end
39
+
40
+ it "returns the proper i18n string for complex usage" do
41
+ expect(product.short_category).to eql(
42
+ I18n.t('product.category.short')
43
+ )
44
+
45
+ expect(product.long_category).to eql(
46
+ I18n.t('product.category.long')
47
+ )
48
+ end
49
+ end
50
+
51
+ describe "#i18n_accessor with Active Hash" do
52
+ let(:grade) { Grade.first }
53
+
54
+ it "returns the proper i18n string for a simple usage" do
55
+ expect(grade.name).to eql( I18n.t('grade.name') )
56
+ end
57
+
58
+ it "returns the proper i18n string for complex usage" do
59
+ expect(grade.long_abbreviation).to eql("Kindergarten")
60
+
61
+ expect(grade.short_abbreviation).to eql("K")
62
+ end
63
+ end
64
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: i18n_accessor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Peregrinator
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-10-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: &70313951055400 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70313951055400
25
+ - !ruby/object:Gem::Dependency
26
+ name: bundler
27
+ requirement: &70313951054140 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '1.7'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70313951054140
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &70313951052640 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '10.0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70313951052640
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &70313951051880 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 3.3.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70313951051880
58
+ - !ruby/object:Gem::Dependency
59
+ name: active_hash
60
+ requirement: &70313951051160 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 1.4.0
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70313951051160
69
+ description: see README
70
+ email:
71
+ - bob.burbach@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - CHANGELOG.md
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - i18n_accessor-0.1.0.gem
83
+ - i18n_accessor.gemspec
84
+ - lib/i18n_accessor.rb
85
+ - lib/i18n_accessor/version.rb
86
+ - spec/fixtures/locales/en.yml
87
+ - spec/i18n_accessor_spec.rb
88
+ homepage: http://github.com/criticaljuncture/i18n_accessor
89
+ licenses:
90
+ - MIT
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 1.8.11
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: Makes keys in your I18N files accessible as methods.
113
+ test_files:
114
+ - spec/fixtures/locales/en.yml
115
+ - spec/i18n_accessor_spec.rb