phene-i18n_auto_scoping 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +15 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +16 -0
- data/Rakefile +14 -0
- data/init.rb +1 -0
- data/lib/action_view_extension.rb +19 -0
- data/lib/i18n_auto_scoping.rb +129 -0
- data/spec/app/views/_partial.erb +1 -0
- data/spec/app/views/folder/_partial.erb +1 -0
- data/spec/app/views/nested.erb +1 -0
- data/spec/app/views/nested_nested.erb +1 -0
- data/spec/app/views/view.erb +1 -0
- data/spec/app/views/view_with_temporarly_change.erb +3 -0
- data/spec/i18n_auto_scoping/i18n_auto_scoping_spec.rb +42 -0
- data/spec/locales/en.yml +13 -0
- data/spec/spec_helper.rb +21 -0
- metadata +99 -0
data/CHANGELOG.rdoc
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Guillaume Luccisano - g-mai|: guillaume.luccisano
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
= I18nAutoScoping
|
2
|
+
|
3
|
+
I18nAutoScoping is a plugin for Ruby on Rails that lets you easily add auto-scope in your I18n translations.
|
4
|
+
It is very useful if you do not want to add every time the scope in your views ! Especially if your are working on big projects !
|
5
|
+
|
6
|
+
All necessary informations are available on the wiki : http://wiki.github.com/kwi/i18n_autoscoping
|
7
|
+
|
8
|
+
* I18nAutoScoping is thread safe.
|
9
|
+
* I18nAutoScoping works with Rails 2.x and Rails 3
|
10
|
+
|
11
|
+
== TODO
|
12
|
+
|
13
|
+
* Another bug fix ?
|
14
|
+
|
15
|
+
|
16
|
+
Copyright (c) 2010 Guillaume Luccisano - g-mai|: guillaume.luccisano, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'spec/rake/spectask'
|
4
|
+
|
5
|
+
spec_files = Rake::FileList["spec/**/*_spec.rb"]
|
6
|
+
|
7
|
+
|
8
|
+
desc "Run specs for current Rails version"
|
9
|
+
Spec::Rake::SpecTask.new do |t|
|
10
|
+
t.spec_files = spec_files
|
11
|
+
t.spec_opts = ["-c"]
|
12
|
+
end
|
13
|
+
|
14
|
+
task :default => :spec
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'i18n_auto_scoping'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Auto scoping for ActionView
|
2
|
+
module ActionView
|
3
|
+
class Base
|
4
|
+
alias_method :i18n_auto_scoping_aliased_render, :render
|
5
|
+
|
6
|
+
# To set a default scope for all render
|
7
|
+
def render(opts = {}, *args)
|
8
|
+
old_auto_scope_in_render = Thread.current[:last_i18n_auto_scope_render_in_render]
|
9
|
+
old_auto_scope = Thread.current[:last_i18n_auto_scope_render]
|
10
|
+
Thread.current[:last_i18n_auto_scope_render_in_render] = true
|
11
|
+
Thread.current[:last_i18n_auto_scope_render] = nil
|
12
|
+
|
13
|
+
i18n_auto_scoping_aliased_render(opts, *args)
|
14
|
+
ensure
|
15
|
+
Thread.current[:last_i18n_auto_scope_render] = old_auto_scope
|
16
|
+
Thread.current[:last_i18n_auto_scope_render_in_render] = old_auto_scope_in_render
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module I18nAutoScoping
|
2
|
+
module ActionControllerDefaultScope
|
3
|
+
|
4
|
+
def set_default_i18n_scope
|
5
|
+
I18n::Scope.default = "controllers/#{params[:controller]}"
|
6
|
+
end
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
module I18nExtension
|
11
|
+
|
12
|
+
def self.included(mod)
|
13
|
+
mod.class_eval do
|
14
|
+
class << self
|
15
|
+
alias_method :i18n_auto_scoping_backend=, :backend=
|
16
|
+
|
17
|
+
def backend=(backend)
|
18
|
+
r = send(:i18n_auto_scoping_backend=, backend)
|
19
|
+
# When assigning a new backend, we try to extend it :
|
20
|
+
extend_backend_for_i18n_auto_scoping
|
21
|
+
r
|
22
|
+
end
|
23
|
+
|
24
|
+
def extend_backend_for_i18n_auto_scoping
|
25
|
+
# Only extend the backend for auto scoping if it had not been already done
|
26
|
+
if !backend.methods.include?('i18n_auto_scoping_translate')
|
27
|
+
backend.extend ::I18nAutoScoping::BackendExtension
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
module BackendExtension
|
39
|
+
|
40
|
+
def self.extended(k)
|
41
|
+
k.class_eval do
|
42
|
+
alias_method :i18n_auto_scoping_translate, :translate
|
43
|
+
|
44
|
+
# Override translate method in order to set autoscoping
|
45
|
+
def translate(locale, key, options = {})
|
46
|
+
# Set the default scope if needed
|
47
|
+
if !options.has_key?(:scope) or options[:scope] == :autoscoping
|
48
|
+
options[:scope] = I18n::Scope.default
|
49
|
+
end
|
50
|
+
|
51
|
+
begin
|
52
|
+
result = i18n_auto_scoping_translate(locale, key, options)
|
53
|
+
rescue I18n::MissingTranslationData
|
54
|
+
options.delete :scope
|
55
|
+
result = i18n_auto_scoping_translate(locale, key, options)
|
56
|
+
end
|
57
|
+
result
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
#i18n extension for having default namespacing
|
66
|
+
module I18n
|
67
|
+
module Scope
|
68
|
+
class << self
|
69
|
+
# Set a default scope
|
70
|
+
def default=(scope)
|
71
|
+
Thread.current[:i18n_default_scope] = (scope.is_a?(String)) ? scope.gsub('/', '.') : scope
|
72
|
+
end
|
73
|
+
|
74
|
+
def default
|
75
|
+
# Temporarly default scope go first
|
76
|
+
return Thread.current[:i18n_temporarly_default_scope] if Thread.current[:i18n_temporarly_default_scope]
|
77
|
+
|
78
|
+
# Then, if we are in a render, we try to get the current scope by scanning the caller stack
|
79
|
+
if Thread.current[:last_i18n_auto_scope_render_in_render]
|
80
|
+
# Cache the analyse of the caller stack result for performance
|
81
|
+
return (Thread.current[:last_i18n_auto_scope_render] ||= get_scope_views_context)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Finally, if there is no scope before, return the default scope
|
85
|
+
Thread.current[:i18n_default_scope]
|
86
|
+
end
|
87
|
+
|
88
|
+
# Inspired from : http://github.com/yar/simple_loc_compat
|
89
|
+
# Return the current view file, only work in app/views folder
|
90
|
+
def get_scope_views_context
|
91
|
+
stack_to_analyse = caller
|
92
|
+
latest_app_file = caller.detect { |level| level =~ /.*\/app\/views\// }
|
93
|
+
return nil unless latest_app_file
|
94
|
+
|
95
|
+
scope = latest_app_file.match(/([^:]+):\d+.*/)[1]
|
96
|
+
path = scope.split('/app/views/').last
|
97
|
+
scope = File.basename(path).split('.').shift
|
98
|
+
# If there is a second extension we keep it, in order to work with .erb.html or .erb.iphone, etc...
|
99
|
+
scope = "#{File.dirname(path)}/#{scope}" if File.dirname(path) != '.'
|
100
|
+
|
101
|
+
scope.gsub!('/', '.')
|
102
|
+
|
103
|
+
scope.to_sym
|
104
|
+
end
|
105
|
+
|
106
|
+
def temporarly_change(scope)
|
107
|
+
old = Thread.current[:i18n_temporarly_default_scope]
|
108
|
+
Thread.current[:i18n_temporarly_default_scope] = scope
|
109
|
+
r = yield
|
110
|
+
Thread.current[:i18n_temporarly_default_scope] = old
|
111
|
+
return r
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
if defined? ActionView
|
119
|
+
require 'action_view_extension'
|
120
|
+
end
|
121
|
+
|
122
|
+
I18n.send :include, I18nAutoScoping::I18nExtension
|
123
|
+
I18n.extend_backend_for_i18n_auto_scoping
|
124
|
+
|
125
|
+
# Auto namespacing default in controller : controllers/controller_name
|
126
|
+
if defined? ActionController
|
127
|
+
ActionController::Base.send :include, I18nAutoScoping::ActionControllerDefaultScope
|
128
|
+
ActionController::Base.send :before_filter, :set_default_i18n_scope
|
129
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= I18n.t(:hi) %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= I18n.t(:hi) %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => 'partial' %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render 'folder/partial' %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= I18n.t(:hi) %>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe :i18n_auto_scoping do
|
4
|
+
before(:all) do
|
5
|
+
@v = ActionView::Base.new([File.join(File.dirname(__FILE__), '../app/views/')], {}, FakeController.new)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should still keep working without scope" do
|
9
|
+
I18n.t(:hi).should == 'Hello'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should still keep working with scope" do
|
13
|
+
I18n.t(:hi, :scope => :bam).should == 'Hello in Bam'
|
14
|
+
end
|
15
|
+
|
16
|
+
it "Should works with scope temporarly changed" do
|
17
|
+
I18n::Scope.temporarly_change(:test_scope) do
|
18
|
+
I18n.t(:hi).should == 'Hello in Test Scope'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "Should works with action view template" do
|
23
|
+
@v.render(:file => 'view').should == 'Hello in view'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "Should work with action view partial without the underscore" do
|
27
|
+
@v.render('partial').should == 'Hello in partial'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "Should works with action view nested template" do
|
31
|
+
@v.render(:file => 'nested').should == 'Hello in partial'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "Should works with action view nested nested template" do
|
35
|
+
@v.render(:file => 'nested_nested').should == 'Hello in nested partial'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "Should works with scope temporarly changed in view" do
|
39
|
+
@v.render(:file => 'view_with_temporarly_change').should == 'Hello in Test Scope'
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
data/spec/locales/en.yml
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
require 'i18n'
|
5
|
+
require 'action_controller'
|
6
|
+
require 'action_view'
|
7
|
+
|
8
|
+
# Add I18n load_path
|
9
|
+
I18n.load_path = (I18n.load_path << Dir[File.join(File.dirname(__FILE__), 'locales', '*.yml')]).uniq
|
10
|
+
|
11
|
+
require File.dirname(__FILE__) + '/../init.rb'
|
12
|
+
|
13
|
+
class FakeController
|
14
|
+
def self.method_missing(meth)
|
15
|
+
return nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def params
|
19
|
+
{:controller => :fake, :action => :show}
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: phene-i18n_auto_scoping
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 6
|
10
|
+
version: 0.2.6
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Geoffrey Hichborn
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-09-14 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: i18n
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 25
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 3
|
33
|
+
- 5
|
34
|
+
version: 0.3.5
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description: I18nAutoScoping is a plugin for Ruby on Rails that lets you easily add auto-scope in your I18n translation. It is very useful if you do not want to add every time the scope in your views ! Especially if your are working on big projects !
|
38
|
+
email: geoff@socialcast.com
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
files:
|
46
|
+
- lib/action_view_extension.rb
|
47
|
+
- lib/i18n_auto_scoping.rb
|
48
|
+
- spec/app/views/_partial.erb
|
49
|
+
- spec/app/views/folder/_partial.erb
|
50
|
+
- spec/app/views/nested.erb
|
51
|
+
- spec/app/views/nested_nested.erb
|
52
|
+
- spec/app/views/view.erb
|
53
|
+
- spec/app/views/view_with_temporarly_change.erb
|
54
|
+
- spec/i18n_auto_scoping/i18n_auto_scoping_spec.rb
|
55
|
+
- spec/locales/en.yml
|
56
|
+
- spec/spec_helper.rb
|
57
|
+
- CHANGELOG.rdoc
|
58
|
+
- MIT-LICENSE
|
59
|
+
- Rakefile
|
60
|
+
- README.rdoc
|
61
|
+
- init.rb
|
62
|
+
has_rdoc: true
|
63
|
+
homepage: http://github.com/phene/i18n_auto_scoping
|
64
|
+
licenses: []
|
65
|
+
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 3
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
version: "0"
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 19
|
86
|
+
segments:
|
87
|
+
- 1
|
88
|
+
- 3
|
89
|
+
- 4
|
90
|
+
version: 1.3.4
|
91
|
+
requirements: []
|
92
|
+
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 1.3.7
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: I18nAutoScoping lets you easily add auto-scope in your I18n translations for your Rails' views.
|
98
|
+
test_files: []
|
99
|
+
|