object_scoped_i18n 0.1.0

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.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
@@ -0,0 +1,62 @@
1
+ = object_scoped_i18n
2
+
3
+ Translate using i18n and scope accoring to the object's place in Ruby's
4
+ hierarchial structure.
5
+
6
+ To use, extend the class:
7
+
8
+ class Admin < User
9
+ extend ObjectScopedI18n
10
+ end
11
+
12
+ You can now call translations on the object:
13
+
14
+ Admin.translate(:name)
15
+
16
+ Which calls I18n like this:
17
+
18
+ I18n.translate(:"admin.name", :default => [:"user.name", :"object.name"])
19
+
20
+ Which looks up "admin.name" first; if it didn't found that, it looks up
21
+ "user.name", including any included modules, all way up.
22
+
23
+ Namespaces are introduced as extra scope.
24
+
25
+ class SomeModule::SomeClass
26
+ end
27
+
28
+ SomeModule::SomeClass.translate(:name)
29
+
30
+ Will be the same as:
31
+
32
+ I18n.translate(:"some_module.some_class.name", :default => {...})
33
+
34
+ You can off course use all the options you would normally use with I18n.
35
+
36
+ == Why?
37
+
38
+ Because I wanted something that was like ActiveRecord's human_attribute_name,
39
+ but consitently over other objects too.
40
+
41
+ == So what about human_attribute_name?
42
+
43
+ You can override it, so it's use object_scoped_i18n:
44
+
45
+ class ActiveRecord::Base
46
+ extend ObjectScopedI18n
47
+ def self.human_attribute_name(key, options = {})
48
+ translate(key, {:default => key.to_s.humanize, :scope => [:activerecord, :attributes]}.merge(options))
49
+ end
50
+ end
51
+
52
+ You now change the scope if you like. Also, you'll get global translations for
53
+ free, for columns like "created_at" and "updated_at".
54
+
55
+ == Installation
56
+
57
+ Just gem install object_scoped_i18n and require it in your project, like you're used to.
58
+
59
+
60
+ == Copyright
61
+
62
+ Copyright (c) 2009 Iain Hecker. Released under the MIT license.
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "object_scoped_i18n"
8
+ gem.summary = %Q{Translate using i18n and scope it according to the object's place in Ruby's hierarchial structure}
9
+ gem.description = %Q{Translate using i18n and scope it according to the object's place in Ruby's hierarchial structure.
10
+ Using ancestors to build up the default option of I18n.translate. Works in much the same way as ActiveRecords human_attribute_name}
11
+ gem.email = "iain@iain.nl"
12
+ gem.homepage = "http://github.com/iain/object_scoped_i18n"
13
+ gem.authors = ["Iain Hecker"]
14
+ gem.add_development_dependency "rspec", ">= 1.2.9"
15
+ gem.add_dependency "i18n"
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'spec/rake/spectask'
24
+ Spec::Rake::SpecTask.new(:spec) do |spec|
25
+ spec.libs << 'lib' << 'spec'
26
+ spec.spec_files = FileList['spec/**/*_spec.rb']
27
+ end
28
+
29
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.pattern = 'spec/**/*_spec.rb'
32
+ spec.rcov = true
33
+ end
34
+
35
+ task :spec => :check_dependencies
36
+
37
+ task :default => :spec
38
+
39
+ require 'rake/rdoctask'
40
+ Rake::RDocTask.new do |rdoc|
41
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
42
+
43
+ rdoc.rdoc_dir = 'rdoc'
44
+ rdoc.title = "object_scoped_i18n #{version}"
45
+ rdoc.rdoc_files.include('README*')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,69 @@
1
+ require 'i18n' unless Object.const_defined?(:I18n)
2
+
3
+ # Translate using i18n and scope accoring to the object's place in Ruby's
4
+ # hierarchial structure.
5
+ #
6
+ # To use, extend the class:
7
+ #
8
+ # class Admin < User
9
+ # extend ObjectScopedI18n
10
+ # end
11
+ #
12
+ # You can now call translations on the object:
13
+ #
14
+ # Admin.translate(:name)
15
+ #
16
+ # Which calls I18n like this:
17
+ #
18
+ # I18n.translate(:"admin.name", :default => [:"user.name", :"object.name"])
19
+ #
20
+ # Which looks up "admin.name" first; if it didn't found that, it looks up
21
+ # "user.name", including any included modules, all way up.
22
+ #
23
+ # Namespaces are introduced as extra scope.
24
+ #
25
+ # class SomeModule::SomeClass
26
+ # end
27
+ #
28
+ # SomeModule::SomeClass.translate(:name)
29
+ #
30
+ # Will be the same as:
31
+ #
32
+ # I18n.translate(:"some_module.some_class.name", :default => {...})
33
+ #
34
+ # You can off course use all the options you would normally use with I18n.
35
+ module ObjectScopedI18n
36
+
37
+ # Perform a basic translation, depending on the object it was called on.
38
+ def translate(key, options = {}, &block)
39
+ I18n.translate(*object_scoped_i18n_options(key, options.dup), &block)
40
+ end
41
+ alias t translate
42
+
43
+ # Same as 'translate' but raises an exception if no translation was found.
44
+ def translate!(key, options = {}, &block)
45
+ I18n.translate!(*object_scoped_i18n_options(key, options.dup), &block)
46
+ end
47
+ alias t! translate!
48
+
49
+ def object_scoped_i18n_options(key, options = {})
50
+ separator = options[:separator] || I18n.default_separator
51
+ translation_tree = self.ancestors.map do |mod|
52
+ # Yes, this looks like the ActiveSupport#underscore method, but it's
53
+ # a bit different. I needed to have the namespace separator after
54
+ # the downcase method, because I don't want to downcase that.
55
+ # Besides, now this gem doesn't have an ActiveSupport dependency.
56
+ scope_name = mod.to_s.
57
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
58
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
59
+ tr("-", "_").
60
+ downcase.
61
+ gsub(/::/, separator)
62
+ :"#{scope_name}#{separator}#{key}"
63
+ end
64
+ translation_key = translation_tree.shift
65
+ options[:default] = (options[:default] || []) + translation_tree
66
+ [ translation_key, options ]
67
+ end
68
+
69
+ end
@@ -0,0 +1,4 @@
1
+ en:
2
+ translation_scope:
3
+ animal:
4
+ something: some nice translation
@@ -0,0 +1,77 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "ObjectScopedI18n" do
4
+
5
+ describe "#translate" do
6
+
7
+ it "should send a i18n call" do
8
+ I18n.should_receive(:translate).with(:foo, :bar)
9
+ Monkey.should_receive(:object_scoped_i18n_options).with(:some_method, {}).and_return([:foo, :bar])
10
+ Monkey.translate(:some_method)
11
+ end
12
+
13
+ it "should alias to 't'" do
14
+ I18n.should_receive(:translate).with(:foo, :bar)
15
+ Monkey.should_receive(:object_scoped_i18n_options).with(:some_method, {}).and_return([:foo, :bar])
16
+ Monkey.t(:some_method)
17
+ end
18
+
19
+ end
20
+
21
+ describe "#translate!" do
22
+
23
+ it "should send a i18n call" do
24
+ I18n.should_receive(:translate!).with(:foo, :bar)
25
+ Monkey.should_receive(:object_scoped_i18n_options).with(:some_method, {}).and_return([:foo, :bar])
26
+ Monkey.translate!(:some_method)
27
+ end
28
+
29
+ it "should alias to 't!'" do
30
+ I18n.should_receive(:translate!).with(:foo, :bar)
31
+ Monkey.should_receive(:object_scoped_i18n_options).with(:some_method, {}).and_return([:foo, :bar])
32
+ Monkey.t!(:some_method)
33
+ end
34
+
35
+ end
36
+
37
+ describe "#object_scoped_i18n_options" do
38
+
39
+ it "should scope properly" do # Look at locale.yml to see what happened
40
+ Monkey.t!(:something, :scope => "translation_scope")
41
+ end
42
+
43
+ it "should translate scoped" do
44
+ subject = Scoped::SomeClass.object_scoped_i18n_options(:my_method)
45
+ subject[0].should == :"scoped.some_class.my_method"
46
+ end
47
+
48
+ it "should know an included module" do
49
+ subject = Scoped::SomeClass.object_scoped_i18n_options(:my_method)
50
+ subject[1][:default][0].should == :"scoped.included_module.my_method"
51
+ end
52
+
53
+ it "should know super class" do
54
+ subject = Scoped::SomeClass.object_scoped_i18n_options(:my_method)
55
+ subject[1][:default][1].should == :"scoped.super_class.my_method"
56
+ end
57
+
58
+ it "should override separator" do
59
+ subject = Monkey.object_scoped_i18n_options(:my_method, :separator => "X")
60
+ subject[0].should == :"monkeyXmy_method"
61
+ end
62
+
63
+ it "should use I18n's default separator" do
64
+ old_separator, I18n.default_separator = I18n.default_separator, "Y"
65
+ subject = Monkey.object_scoped_i18n_options(:my_method)
66
+ subject[0].should == :"monkeyYmy_method"
67
+ I18n.default_separator = old_separator
68
+ end
69
+
70
+ it "should leave other options untouched" do
71
+ subject = Monkey.object_scoped_i18n_options(:my_method, :my_options => "x")
72
+ subject[1][:my_options].should == "x"
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,30 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'object_scoped_i18n'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
10
+
11
+ I18n.load_path << File.dirname(__FILE__) + '/locale.yml'
12
+
13
+ module Scoped
14
+ module IncludedModule
15
+ end
16
+ class SuperClass
17
+ end
18
+ class SomeClass < SuperClass
19
+ extend ObjectScopedI18n
20
+ include IncludedModule
21
+ end
22
+ end
23
+
24
+ class Animal
25
+ extend ObjectScopedI18n
26
+ end
27
+
28
+ class Monkey < Animal
29
+
30
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: object_scoped_i18n
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Iain Hecker
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-13 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.9
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: i18n
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ description: |-
36
+ Translate using i18n and scope it according to the object's place in Ruby's hierarchial structure.
37
+ Using ancestors to build up the default option of I18n.translate. Works in much the same way as ActiveRecords human_attribute_name
38
+ email: iain@iain.nl
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - README.rdoc
45
+ files:
46
+ - .document
47
+ - .gitignore
48
+ - README.rdoc
49
+ - Rakefile
50
+ - VERSION
51
+ - lib/object_scoped_i18n.rb
52
+ - spec/locale.yml
53
+ - spec/object_scoped_i18n_spec.rb
54
+ - spec/spec.opts
55
+ - spec/spec_helper.rb
56
+ has_rdoc: true
57
+ homepage: http://github.com/iain/object_scoped_i18n
58
+ licenses: []
59
+
60
+ post_install_message:
61
+ rdoc_options:
62
+ - --charset=UTF-8
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ requirements: []
78
+
79
+ rubyforge_project:
80
+ rubygems_version: 1.3.5
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Translate using i18n and scope it according to the object's place in Ruby's hierarchial structure
84
+ test_files:
85
+ - spec/object_scoped_i18n_spec.rb
86
+ - spec/spec_helper.rb