missing_i18n 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.
- checksums.yaml +15 -0
- data/MIT-LICENSE +20 -0
- data/README.md +68 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/missing_i18n/application.js +11 -0
- data/app/assets/stylesheets/missing_i18n/application.css.erb +36 -0
- data/app/controllers/missing_i18n/application_controller.rb +7 -0
- data/app/controllers/missing_i18n/locales_controller.rb +17 -0
- data/app/models/missing_i18n/locale.rb +90 -0
- data/app/views/layouts/missing_i18n/application.html.erb +14 -0
- data/app/views/missing_i18n/locales/_locale.html.erb +5 -0
- data/app/views/missing_i18n/locales/index.html.erb +19 -0
- data/app/views/missing_i18n/locales/show.html.erb +15 -0
- data/config/routes.rb +4 -0
- data/lib/missing_i18n/engine.rb +5 -0
- data/lib/missing_i18n/version.rb +3 -0
- data/lib/missing_i18n.rb +29 -0
- data/script/rails +8 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +12 -0
- data/test/dummy/config/application.rb +61 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +6 -0
- data/test/dummy/config/locales/es.yml +9 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/log/development.log +3702 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/tmp/cache/assets/C37/460/sprockets%2F2c97f7629d838469e984005b45012f74 +0 -0
- data/test/dummy/tmp/cache/assets/C57/090/sprockets%2Ffb76e34f34542c751920190a976075c7 +0 -0
- data/test/dummy/tmp/cache/assets/C7A/AE0/sprockets%2F805bd3ef634444b405484a146381c6f2 +0 -0
- data/test/dummy/tmp/cache/assets/C85/6B0/sprockets%2F721d069a93d238f5396bf503b5b15594 +0 -0
- data/test/dummy/tmp/cache/assets/C8A/340/sprockets%2F7455c226fe9a93805641c9d1e38453a5 +0 -0
- data/test/dummy/tmp/cache/assets/C9A/670/sprockets%2F982543409941ce9c29dc44a78f4c0988 +0 -0
- data/test/dummy/tmp/cache/assets/CB3/D00/sprockets%2F00a9467f9e3685b6eb224e03379b28b2 +0 -0
- data/test/dummy/tmp/cache/assets/CE0/370/sprockets%2Fa39a8740f0b61611a6f9b9756fd9b211 +0 -0
- data/test/dummy/tmp/cache/assets/CE3/230/sprockets%2F218faa25364da35b59b68638b73ca567 +0 -0
- data/test/dummy/tmp/cache/assets/D0B/A40/sprockets%2F57f31167761f8b26bc3f1b0167bb4e3f +0 -0
- data/test/dummy/tmp/cache/assets/D14/CC0/sprockets%2F413b47ad449f6c649da1a76de9c52740 +0 -0
- data/test/dummy/tmp/cache/assets/D1A/BA0/sprockets%2F8f568f3083278618c50c82d1bbcf6dc5 +0 -0
- data/test/dummy/tmp/cache/assets/D20/D90/sprockets%2F7a9daf4472f16222b989f0f69c9820eb +0 -0
- data/test/dummy/tmp/cache/assets/D27/130/sprockets%2Fc3fee9098e52c52368f4eb9722ef9182 +0 -0
- data/test/dummy/tmp/cache/assets/D32/080/sprockets%2F8b1af3a2afe11e950164bec706f64191 +0 -0
- data/test/dummy/tmp/cache/assets/D3D/400/sprockets%2Ff3a0fc08891cc4e1e05f219c8827dd40 +0 -0
- data/test/dummy/tmp/cache/assets/D4A/250/sprockets%2F0ad7a77a58513a939a16f7b87fd742fc +0 -0
- data/test/dummy/tmp/cache/assets/D54/650/sprockets%2F95c28117b88ef818d27e1d2f9ca8bc58 +0 -0
- data/test/dummy/tmp/cache/assets/D64/6C0/sprockets%2Fe5bf1f16b921a3c2050657e8c3fcc51e +0 -0
- data/test/dummy/tmp/cache/assets/D74/6F0/sprockets%2Fd70538680abddce9109f2c6ef271ff07 +0 -0
- data/test/dummy/tmp/cache/assets/D76/F70/sprockets%2F46dfa9faaf2928d59b22da4442dd1957 +0 -0
- data/test/dummy/tmp/cache/assets/D86/640/sprockets%2F286d910145a2ea0cc8cda9acb442c06a +0 -0
- data/test/dummy/tmp/cache/assets/D8F/560/sprockets%2F057d1cb22221eecd76f281af2f6bd43c +0 -0
- data/test/dummy/tmp/cache/assets/DA2/EB0/sprockets%2Fcb0b147573bea528d5de16ce97c65a7f +0 -0
- data/test/dummy/tmp/cache/assets/DA5/7B0/sprockets%2F3cb24755d374c7f515eef2bfd548cde2 +0 -0
- data/test/dummy/tmp/cache/assets/DC9/9F0/sprockets%2Fb6cf7b756a0d77db1e530ad74072dbef +0 -0
- data/test/dummy/tmp/pids/server.pid +1 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/missing_i18n_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- data/vendor/assets/images/glyphicons-halflings-white.png +0 -0
- data/vendor/assets/images/glyphicons-halflings.png +0 -0
- data/vendor/assets/javascripts/bootstrap.min.js +6 -0
- data/vendor/assets/javascripts/jquery-1.8.3.min.js +2 -0
- data/vendor/assets/stylesheets/bootstrap.min.css +9 -0
- metadata +217 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
!binary "U0hBMQ==":
|
|
3
|
+
metadata.gz: !binary |-
|
|
4
|
+
YmIwNDA0MmM3ODk5YTY2NDk2YmFiMDEyY2I5YzQyYjY5ZWM3ZDE3Yw==
|
|
5
|
+
data.tar.gz: !binary |-
|
|
6
|
+
MjU4YjNjMGY0ZTBkYTM5MGE5YjExZjU3ZjJiMTgxMDJjM2MxZGVhYQ==
|
|
7
|
+
!binary "U0hBNTEy":
|
|
8
|
+
metadata.gz: !binary |-
|
|
9
|
+
NGY3MDM0MjAzZWQwNzUyMGQxYjEyNjY1ZDhmYWViMTAzYmYwMmIzZTFmYmFh
|
|
10
|
+
MGI1NWU3Y2NjYTRiODQ5M2YwYWY1Njc0YTg1MWMyY2FlMzIyYjNkODg3ZTg5
|
|
11
|
+
MDY0YjNkNmJhZmJhNDlkNmYwMjlhNDFhODBkYTM5YTE1MDBkNzA=
|
|
12
|
+
data.tar.gz: !binary |-
|
|
13
|
+
YTE3M2Q2OWFkMTJhMjIxYmU3N2I3Mzg0ZmNmZTAyMGE1YzY3OThkMmY1Yzg2
|
|
14
|
+
NjgxODU2MmQyMWU1NDUxZjY3MTE5OTVjNGY3ZWYzMmJhZWMwOTY2NjFiOTQ2
|
|
15
|
+
N2Y4YjE5N2VkNDkwOWU5OGNmY2RmODc2ZWIwNDFiZGNjYmIyODM=
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2013 YOURNAME
|
|
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.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# missing_i18n
|
|
2
|
+
|
|
3
|
+
This is a [rails 3 mountable engine](http://railscasts.com/episodes/277-mountable-engines).
|
|
4
|
+
|
|
5
|
+
It allows you to see which locales have missing entries. You probably want to use it in your development/staging environment.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
On your Gemfile:
|
|
10
|
+
|
|
11
|
+
gem 'missing_i18n'
|
|
12
|
+
|
|
13
|
+
On your `config/routes.rb`:
|
|
14
|
+
|
|
15
|
+
unless Rails.env.production? # optional, but recommended
|
|
16
|
+
mount MissingI18n::Engine, :path => '/missing_i18n'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
## Customization & scope filtering
|
|
20
|
+
|
|
21
|
+
You can override MissingI18n' only view by creating any of the following files:
|
|
22
|
+
|
|
23
|
+
* `app/views/missing_i18n/locales/index.html.erb`
|
|
24
|
+
* `app/views/missing_i18n/locales/show.html.erb`
|
|
25
|
+
|
|
26
|
+
You can similarly override MissingI18n controller by defining `app/views/missing_i18n/locales_controller.rb`.
|
|
27
|
+
|
|
28
|
+
Finally, you will probably want to add "ignored paths" to `missing_i18n`, for example for avoiding certain groups of prefixes.
|
|
29
|
+
|
|
30
|
+
To ignore (for example) the entries inserted by the [Faker](http://faker.rubyforge.org/), create an initializer file with this text:
|
|
31
|
+
|
|
32
|
+
# config/initializers/missing_i18n.rb
|
|
33
|
+
|
|
34
|
+
if defined? MissingI18n
|
|
35
|
+
MissingI18n.ignored_scopes += ['faker']
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
You can add more than one scope on that array. Also, you can add dot-separated scopes (`'foo.bar.baz'`) to filter more precisely.
|
|
39
|
+
|
|
40
|
+
Notice that `missing_i18n` [ignores some scopes by default](https://github.com/kikito/missing_i18n/blob/master/lib/missing_i18n.rb). These are scopes missing in some
|
|
41
|
+
locales of [rails-i18n](https://github.com/svenfuchs/rails-i18n), and in general it is safe to ignore those. If you need to include them in the list, you can; just
|
|
42
|
+
set `MissingI18n.ignored_scopes` to whatever you want; just use `=` instead of `+=`:
|
|
43
|
+
|
|
44
|
+
# config/initializers/missing_i18n.rb
|
|
45
|
+
|
|
46
|
+
if defined? MissingI18n
|
|
47
|
+
MissingI18n.ignored_scopes = ['my.scopes', 'which.dont.include', 'the.default.ones']
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
Everything will work as long as `MissingI18n.ignored_scopes` is an array of strings.
|
|
51
|
+
|
|
52
|
+
## Tests
|
|
53
|
+
|
|
54
|
+
This engine has no tests. I'm basically using non-public methods from the i18n gem, so it's extremely brittle and coupled with the implementation details of i18n.
|
|
55
|
+
|
|
56
|
+
However, you can try the dummy app by executing:
|
|
57
|
+
|
|
58
|
+
cd test/dummy
|
|
59
|
+
rails s
|
|
60
|
+
|
|
61
|
+
If you then go to http://localhost:3000, you should see some differences between the es and en locales. Try modifying the files inside `test/dummy/config/locales` and
|
|
62
|
+
refreshing the page.
|
|
63
|
+
|
|
64
|
+
Feel free to send me pull requests with tests if you want!
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
data/Rakefile
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env rake
|
|
2
|
+
begin
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
rescue LoadError
|
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
6
|
+
end
|
|
7
|
+
begin
|
|
8
|
+
require 'rdoc/task'
|
|
9
|
+
rescue LoadError
|
|
10
|
+
require 'rdoc/rdoc'
|
|
11
|
+
require 'rake/rdoctask'
|
|
12
|
+
RDoc::Task = Rake::RDocTask
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
17
|
+
rdoc.title = 'MissingI18n'
|
|
18
|
+
rdoc.options << '--line-numbers'
|
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
|
24
|
+
load 'rails/tasks/engine.rake'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
Bundler::GemHelper.install_tasks
|
|
29
|
+
|
|
30
|
+
require 'rake/testtask'
|
|
31
|
+
|
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
|
33
|
+
t.libs << 'lib'
|
|
34
|
+
t.libs << 'test'
|
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
|
36
|
+
t.verbose = false
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
task :default => :test
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//= require jquery-1.8.3.min
|
|
2
|
+
//= require_tree .
|
|
3
|
+
|
|
4
|
+
jQuery(function($) {
|
|
5
|
+
$('.locales').on('click', 'li', function() {
|
|
6
|
+
var $li = $(this);
|
|
7
|
+
$('iframe').attr('src', $li.find('a').attr('href'));
|
|
8
|
+
$li.parent().find('.active').removeClass('active');
|
|
9
|
+
$li.addClass('active');
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*= require bootstrap.min
|
|
3
|
+
*= require_self
|
|
4
|
+
*= require_tree .
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
body {
|
|
8
|
+
height: 100%;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
iframe {
|
|
12
|
+
min-height: 95%;
|
|
13
|
+
width: 100%;
|
|
14
|
+
border: none;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.locales li {
|
|
18
|
+
list-style-type: none;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.locales .active,
|
|
22
|
+
.locales .active:hover {
|
|
23
|
+
background: #ccc;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.locales li {
|
|
27
|
+
cursor: pointer;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
[class^="icon-"], [class*=" icon-"] {
|
|
31
|
+
background-image: url(<%=asset_path "glyphicons-halflings.png"%>);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.icon-white {
|
|
35
|
+
background-image: url(<%=asset_path "glyphicons-halflings-white.png"%>);
|
|
36
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module MissingI18n
|
|
2
|
+
class LocalesController < ApplicationController
|
|
3
|
+
def index
|
|
4
|
+
@locales = Locale.all
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def show
|
|
8
|
+
@locale = Locale.new(params[:id])
|
|
9
|
+
respond_to do |format|
|
|
10
|
+
format.html
|
|
11
|
+
format.yaml {
|
|
12
|
+
render :text => @locale.to_yaml, :content_type => 'text/yaml'
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module MissingI18n
|
|
2
|
+
class Locale #plain old ruby object
|
|
3
|
+
|
|
4
|
+
@@merged_translations = nil
|
|
5
|
+
@@i18n_translations = nil
|
|
6
|
+
@@all = nil
|
|
7
|
+
|
|
8
|
+
attr_accessor :id
|
|
9
|
+
|
|
10
|
+
def initialize(id)
|
|
11
|
+
self.id = id.to_s
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_yaml(ignored_scopes = MissingI18n.ignored_scopes)
|
|
15
|
+
{self.id => missing_i18n(ignored_scopes)}.to_yaml
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def translations
|
|
19
|
+
self.class.i18n_translations[self.id]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def missing_i18n(ignored_scopes = MissingI18n.ignored_scopes)
|
|
23
|
+
diff = hash_deep_diff(self.class.merged_translations, self.translations)
|
|
24
|
+
return hash_filter(diff, [], ignored_scopes)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.all
|
|
28
|
+
@@all ||= I18n.available_locales.collect{ |id| new(id) }.sort_by(&:id)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.merged_translations
|
|
32
|
+
unless @@merged_translations
|
|
33
|
+
@@merged_translations = {}
|
|
34
|
+
i18n_translations.each do |locale, translations|
|
|
35
|
+
@@merged_translations = translations.deep_merge(@@merged_translations)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
@@merged_translations
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.i18n_translations
|
|
42
|
+
unless @@i18n_translations
|
|
43
|
+
I18n.backend.send :init_translations
|
|
44
|
+
@@i18n_translations = hash_deep_stringify_keys(I18n.backend.send(:translations))
|
|
45
|
+
end
|
|
46
|
+
@@i18n_translations
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def hash_filter(hash, scope, ignored_scopes)
|
|
53
|
+
return hash unless hash.is_a? Hash
|
|
54
|
+
result = {}
|
|
55
|
+
hash.each do |key, value|
|
|
56
|
+
new_scope = scope.dup << key
|
|
57
|
+
unless new_scope.join('.').in?(ignored_scopes)
|
|
58
|
+
new_value = hash_filter(value, new_scope, ignored_scopes)
|
|
59
|
+
result[key] = new_value unless new_value.blank?
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
result
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# assumption big contains small completely
|
|
66
|
+
def hash_deep_diff(big, small)
|
|
67
|
+
return big unless small.is_a? Hash
|
|
68
|
+
result = {}
|
|
69
|
+
big.each do |key, value|
|
|
70
|
+
if small[key].present?
|
|
71
|
+
if value.is_a?(Hash)
|
|
72
|
+
diff = hash_deep_diff(value, small[key])
|
|
73
|
+
result[key] = diff unless diff.empty?
|
|
74
|
+
end
|
|
75
|
+
else
|
|
76
|
+
result[key] = value
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
result
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def self.hash_deep_stringify_keys(hash)
|
|
83
|
+
return hash unless hash.is_a? Hash
|
|
84
|
+
hash.each_with_object({}) do |(key,value), result|
|
|
85
|
+
result[key.to_s] = hash_deep_stringify_keys(value)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>missing_i18n</title>
|
|
5
|
+
<%= stylesheet_link_tag "missing_i18n/application", :media => "all" %>
|
|
6
|
+
<%= javascript_include_tag "missing_i18n/application" %>
|
|
7
|
+
<%= csrf_meta_tags %>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
|
|
11
|
+
<%= yield %>
|
|
12
|
+
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<div class="container">
|
|
2
|
+
<h1>missing_i18n
|
|
3
|
+
<%= link_to locales_path, class: 'btn btn-primary refresh' do %>
|
|
4
|
+
<i class="icon-refresh icon-white"></i>
|
|
5
|
+
Refresh
|
|
6
|
+
<% end %>
|
|
7
|
+
</h1>
|
|
8
|
+
|
|
9
|
+
<ul class="locales inline">
|
|
10
|
+
<% @locales.each_with_index do |locale, index| %>
|
|
11
|
+
<li class="<%= 'active' if index == 0 %>">
|
|
12
|
+
<%= link_to(locale.id, locale_path(locale.id), target: 'locale') %>
|
|
13
|
+
</li>
|
|
14
|
+
<% end %>
|
|
15
|
+
</ul>
|
|
16
|
+
|
|
17
|
+
<iframe name="locale" id="locale" src="<%= @locales[0].present? ? locale_path(@locales[0].id) : 'about:blank' %>"></iframe>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<h2><%= @locale.id %></h2>
|
|
2
|
+
|
|
3
|
+
<pre>
|
|
4
|
+
<%= @locale.to_yaml %>
|
|
5
|
+
</pre>
|
|
6
|
+
|
|
7
|
+
<p class="pull-right">
|
|
8
|
+
<%= link_to locale_path(@locale.id, :format => :yaml),
|
|
9
|
+
:class => 'btn btn-inverse btn-small',
|
|
10
|
+
:target => '_blank' do %>
|
|
11
|
+
<i class="icon-download icon-white"></i>
|
|
12
|
+
yaml
|
|
13
|
+
<% end %>
|
|
14
|
+
</p>
|
|
15
|
+
|
data/config/routes.rb
ADDED
data/lib/missing_i18n.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require "missing_i18n/engine"
|
|
2
|
+
|
|
3
|
+
module MissingI18n
|
|
4
|
+
DEFAULT_IGNORED_SCOPES = %w{
|
|
5
|
+
activemodel.errors.messages
|
|
6
|
+
activemodel.errors.template.header
|
|
7
|
+
activerecord.errors.messages
|
|
8
|
+
activerecord.errors.template.header
|
|
9
|
+
datetime.distance_in_words
|
|
10
|
+
datetime.prompts
|
|
11
|
+
errors.messages
|
|
12
|
+
errors.template.header
|
|
13
|
+
helpers.button
|
|
14
|
+
helpers.select
|
|
15
|
+
helpers.submit
|
|
16
|
+
i18n
|
|
17
|
+
number
|
|
18
|
+
support.array
|
|
19
|
+
time
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
def self.ignored_scopes=(new_ignored_scopes)
|
|
23
|
+
@@ignored_scopes = new_ignored_scopes
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.ignored_scopes
|
|
27
|
+
@@ignored_scopes ||= DEFAULT_IGNORED_SCOPES.clone
|
|
28
|
+
end
|
|
29
|
+
end
|
data/script/rails
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
|
3
|
+
|
|
4
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
|
5
|
+
ENGINE_PATH = File.expand_path('../../lib/missing_i18n/engine', __FILE__)
|
|
6
|
+
|
|
7
|
+
require 'rails/all'
|
|
8
|
+
require 'rails/engine/commands'
|