awesome_translations 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +30 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/awesome_translations/application.js +13 -0
- data/app/assets/stylesheets/awesome_translations/application.css.scss +14 -0
- data/app/assets/stylesheets/awesome_translations/groups.css.scss +18 -0
- data/app/assets/stylesheets/awesome_translations/layout.css.scss +51 -0
- data/app/controllers/awesome_translations/application_controller.rb +4 -0
- data/app/controllers/awesome_translations/groups_controller.rb +38 -0
- data/app/controllers/awesome_translations/handlers_controller.rb +17 -0
- data/app/controllers/awesome_translations/translations_controller.rb +4 -0
- data/app/helpers/awesome_translations/application_helper.rb +4 -0
- data/app/models/awesome_translations/group.rb +43 -0
- data/app/models/awesome_translations/handler.rb +45 -0
- data/app/models/awesome_translations/translated_value.rb +47 -0
- data/app/models/awesome_translations/translation.rb +88 -0
- data/app/views/awesome_translations/groups/show.html.haml +28 -0
- data/app/views/awesome_translations/handlers/index.html.haml +13 -0
- data/app/views/awesome_translations/handlers/show.html.haml +12 -0
- data/app/views/layouts/awesome_translations/application.html.haml +24 -0
- data/config/routes.rb +7 -0
- data/lib/awesome_translations.rb +18 -0
- data/lib/awesome_translations/config.rb +7 -0
- data/lib/awesome_translations/engine.rb +3 -0
- data/lib/awesome_translations/erb_inspector.rb +45 -0
- data/lib/awesome_translations/erb_inspector/file_inspector.rb +88 -0
- data/lib/awesome_translations/erb_inspector/translation_inspector.rb +69 -0
- data/lib/awesome_translations/handlers.rb +25 -0
- data/lib/awesome_translations/handlers/base_handler.rb +2 -0
- data/lib/awesome_translations/handlers/erb_handler.rb +35 -0
- data/lib/awesome_translations/handlers/global_handler.rb +31 -0
- data/lib/awesome_translations/handlers/model_handler.rb +95 -0
- data/lib/awesome_translations/handlers/validations_handler.rb +70 -0
- data/lib/awesome_translations/model_inspector.rb +137 -0
- data/lib/awesome_translations/model_inspector/attribute.rb +12 -0
- data/lib/awesome_translations/object_extensions.rb +13 -0
- data/lib/awesome_translations/version.rb +3 -0
- data/lib/tasks/awesome_translations_tasks.rake +29 -0
- data/spec/controllers/groups_controller_spec.rb +34 -0
- data/spec/controllers/handlers_controller_spec.rb +16 -0
- data/spec/controllers/users_controller_spec.rb +18 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +17 -0
- data/spec/dummy/app/controllers/locales_controller.rb +6 -0
- data/spec/dummy/app/controllers/users_controller.rb +32 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/role.rb +4 -0
- data/spec/dummy/app/models/user.rb +7 -0
- data/spec/dummy/app/views/layouts/application.html.haml +21 -0
- data/spec/dummy/app/views/users/_partial_test.html.haml +1 -0
- data/spec/dummy/app/views/users/index.html.haml +16 -0
- data/spec/dummy/app/views/users/show.html.erb +6 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +28 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +32 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/awesome_translations/app/views/users/da.yml +5 -0
- data/spec/dummy/config/locales/awesome_translations/app/views/users/de.yml +5 -0
- data/spec/dummy/config/locales/awesome_translations/app/views/users/en.yml +5 -0
- data/spec/dummy/config/locales/awesome_translations/da.yml +4 -0
- data/spec/dummy/config/locales/awesome_translations/de.yml +4 -0
- data/spec/dummy/config/locales/awesome_translations/en.yml +4 -0
- data/spec/dummy/config/locales/awesome_translations/models/role/da.yml +6 -0
- data/spec/dummy/config/locales/awesome_translations/models/role/de.yml +6 -0
- data/spec/dummy/config/locales/awesome_translations/models/role/en.yml +6 -0
- data/spec/dummy/config/locales/awesome_translations/models/user/da.yml +12 -0
- data/spec/dummy/config/locales/awesome_translations/models/user/de.yml +12 -0
- data/spec/dummy/config/locales/awesome_translations/models/user/en.yml +12 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +7 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20141018081559_create_users.rb +9 -0
- data/spec/dummy/db/migrate/20141018081640_create_roles.rb +10 -0
- data/spec/dummy/db/schema.rb +29 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +16953 -0
- data/spec/dummy/log/test.log +4992 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/79bc6a1530be4e47bb2bf0dda4943bc0e439789f/application.css.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/79bc6a1530be4e47bb2bf0dda4943bc0e439789f/groups.css.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sass/79bc6a1530be4e47bb2bf0dda4943bc0e439789f/layout.css.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/0cc5658eb161251c8bd64e1cf25e2191 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1dfc909a73e53e47b341f67cfd8a3fc3 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2128d293dc8ef13115c1f5d64b5acfc9 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3bd5629974bb1919d009bcb1da7a7e49 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/50b9bcf05a8718d9cb5b99276f154ea9 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/5316fc0620afefc2ba81b690c8e2c34d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/538966109f3bbd58bfb717ad57a37096 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/58b9ed99ad62ba462ca6a9272b96bef3 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/697d977cf9fc7e54534f5e29b0832836 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6aab60b365535cc305f37a738e75868b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6db8498274efddac6691248cc9afe855 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/81ab882fef1228d654a7c697f2324309 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/908bf508cc68079cab720d6b9c36cb95 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/91090eda0f104056144ac17a4fcae91c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a3c8104e5830cd7047c6a3a1c1e2ba32 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b512f2b016bd3aef8c28fa661e01308c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/bd49bb0a6f5dfd284a750fb9cab40d85 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c39fce5fa19b758734af29527d4185ca +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c8ecba0dbc7774cd6db79cb7fbe1ef3e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cb595904fcf7acdedf2b95571442fc59 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/eb9ed717a7ef467bf260b11dfc8451eb +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sass/79bc6a1530be4e47bb2bf0dda4943bc0e439789f/application.css.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/test/sass/79bc6a1530be4e47bb2bf0dda4943bc0e439789f/groups.css.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/test/sass/79bc6a1530be4e47bb2bf0dda4943bc0e439789f/layout.css.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/2128d293dc8ef13115c1f5d64b5acfc9 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/50b9bcf05a8718d9cb5b99276f154ea9 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/5316fc0620afefc2ba81b690c8e2c34d +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/538966109f3bbd58bfb717ad57a37096 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/58b9ed99ad62ba462ca6a9272b96bef3 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/697d977cf9fc7e54534f5e29b0832836 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/6aab60b365535cc305f37a738e75868b +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/6db8498274efddac6691248cc9afe855 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/81ab882fef1228d654a7c697f2324309 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/908bf508cc68079cab720d6b9c36cb95 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/91090eda0f104056144ac17a4fcae91c +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/a3c8104e5830cd7047c6a3a1c1e2ba32 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/b512f2b016bd3aef8c28fa661e01308c +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/bd49bb0a6f5dfd284a750fb9cab40d85 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/c39fce5fa19b758734af29527d4185ca +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/cb595904fcf7acdedf2b95571442fc59 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/eb9ed717a7ef467bf260b11dfc8451eb +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/factories/user.rb +7 -0
- data/spec/handlers/erb_handler_spec.rb +35 -0
- data/spec/handlers/global_handler_spec.rb +19 -0
- data/spec/handlers/model_handler_spec.rb +30 -0
- data/spec/handlers/validations_handler_spec.rb +25 -0
- data/spec/handlers_spec.rb +9 -0
- data/spec/lib/erb_inspector/file_inspector_spec.rb +21 -0
- data/spec/lib/erb_inspector/translation_inspector_spec.rb +23 -0
- data/spec/lib/erb_inspector_spec.rb +26 -0
- data/spec/models/awesome_translations/handler_spec.rb +8 -0
- data/spec/models/awesome_translations/translated_value_spec.rb +43 -0
- data/spec/spec_helper.rb +56 -0
- metadata +505 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
%h1= "Show group: #{@group.name}"
|
2
|
+
|
3
|
+
= form_for :group, url: handler_group_path(@handler, @group), method: :put do |f|
|
4
|
+
%table
|
5
|
+
%thead
|
6
|
+
%th Key
|
7
|
+
- I18n.available_locales.each do |locale|
|
8
|
+
%th= locale
|
9
|
+
%tbody
|
10
|
+
- @translations.each do |translation|
|
11
|
+
%tr
|
12
|
+
%td= translation.key
|
13
|
+
|
14
|
+
- I18n.available_locales.each do |locale|
|
15
|
+
%td
|
16
|
+
= text_field "t", "#{translation.key}[#{locale}]", value: translation.value(locale: locale)
|
17
|
+
|
18
|
+
- if translation.file_line_content?
|
19
|
+
%tr.line-content-row
|
20
|
+
%td.line-content{colspan: 1 + I18n.available_locales.length}
|
21
|
+
%pre= translation.file_line_content
|
22
|
+
%tr
|
23
|
+
%td.line-spacer{colspan: 1 + I18n.available_locales.length}
|
24
|
+
- if @translations.empty?
|
25
|
+
%tr
|
26
|
+
%td.error{colspan: 2} No translations were found.
|
27
|
+
|
28
|
+
= f.submit "Save"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
!!! 5
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title AwesomeTranslations
|
5
|
+
|
6
|
+
= stylesheet_link_tag "awesome_translations/application", media: "all"
|
7
|
+
= stylesheet_link_tag "http://fonts.googleapis.com/css?family=Open+Sans:400"
|
8
|
+
= stylesheet_link_tag "http://fonts.googleapis.com/css?family=Raleway:400"
|
9
|
+
|
10
|
+
= javascript_include_tag "awesome_translations/application"
|
11
|
+
|
12
|
+
= csrf_meta_tags
|
13
|
+
|
14
|
+
%body{class: ["controller_#{controller_name}", "action_#{action_name}"]}
|
15
|
+
%table.main-table
|
16
|
+
%tbody
|
17
|
+
%tr
|
18
|
+
%td.main-logo Awesome Translations
|
19
|
+
%tr
|
20
|
+
%td.main-menu
|
21
|
+
.menu-item= link_to "Handlers", handlers_path
|
22
|
+
%tr
|
23
|
+
%td.main-content
|
24
|
+
= yield
|
data/config/routes.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "awesome_translations/engine"
|
2
|
+
require "haml"
|
3
|
+
require "string-cases"
|
4
|
+
require "array_enumerator"
|
5
|
+
|
6
|
+
module AwesomeTranslations
|
7
|
+
autoload :Config, "#{File.dirname(__FILE__)}/awesome_translations/config"
|
8
|
+
autoload :ErbInspector, "#{File.dirname(__FILE__)}/awesome_translations/erb_inspector"
|
9
|
+
autoload :Handlers, "#{File.dirname(__FILE__)}/awesome_translations/handlers"
|
10
|
+
autoload :ObjectExtensions, "awesome_translations/object_extensions"
|
11
|
+
autoload :ModelInspector, "awesome_translations/model_inspector"
|
12
|
+
|
13
|
+
def self.config
|
14
|
+
@config ||= AwesomeTranslations::Config.new
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Object.__send__(:include, AwesomeTranslations::ObjectExtensions)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Used to find translations in the Rails app by inspecting .erb- and .haml-files.
|
2
|
+
class AwesomeTranslations::ErbInspector
|
3
|
+
autoload :FileInspector, "#{File.dirname(__FILE__)}/erb_inspector/file_inspector"
|
4
|
+
autoload :TranslationInspector, "#{File.dirname(__FILE__)}/erb_inspector/translation_inspector"
|
5
|
+
|
6
|
+
def initialize(args = {})
|
7
|
+
if args[:dirs]
|
8
|
+
@dirs = args[:dirs]
|
9
|
+
else
|
10
|
+
@dirs = AwesomeTranslations.config.paths_to_translate
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Yields all relevant .erb- and .haml-files.
|
15
|
+
def files
|
16
|
+
Enumerator.new do |yielder|
|
17
|
+
@dirs.each do |dir|
|
18
|
+
scan_dir("", dir, yielder)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def scan_dir(path, root_path, yielder)
|
26
|
+
Dir.foreach("#{root_path}/#{path}") do |file|
|
27
|
+
next if file == "." || file == ".."
|
28
|
+
file_path = "#{path}"
|
29
|
+
file_path << "/" unless file_path.empty?
|
30
|
+
file_path << file
|
31
|
+
|
32
|
+
full_path = "#{root_path}/#{file_path}"
|
33
|
+
ext = File.extname(file_path)
|
34
|
+
|
35
|
+
if File.directory?(full_path)
|
36
|
+
scan_dir(file_path, root_path, yielder)
|
37
|
+
elsif ext == ".erb" || ext == ".haml"
|
38
|
+
yielder << AwesomeTranslations::ErbInspector::FileInspector.new(
|
39
|
+
file_path: file_path,
|
40
|
+
root_path: root_path
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
class AwesomeTranslations::ErbInspector::FileInspector
|
2
|
+
METHOD_NAMES = ["t"]
|
3
|
+
VALID_BEGINNING = '(^|\s+|\(|\{|<%=\s*)'
|
4
|
+
|
5
|
+
attr_reader :root_path, :file_path
|
6
|
+
|
7
|
+
def initialize(args)
|
8
|
+
@args = args
|
9
|
+
@root_path, @file_path = args[:root_path], args[:file_path]
|
10
|
+
end
|
11
|
+
|
12
|
+
def translations
|
13
|
+
Enumerator.new do |yielder|
|
14
|
+
translations_found = {}
|
15
|
+
|
16
|
+
File.open(full_path, "r") do |fp|
|
17
|
+
line_no = 0
|
18
|
+
fp.each_line do |line|
|
19
|
+
line_no += 1
|
20
|
+
parse_content(line_no, line, translations_found, yielder)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def full_path
|
27
|
+
"#{@root_path}/#{@file_path}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def basename
|
31
|
+
File.basename(@file_path).match(/\A(.+?)\./)[1]
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def parse_content(line_no, line, translations_found, yielder)
|
37
|
+
METHOD_NAMES.each do |method_name|
|
38
|
+
# Scan for the various valid formats.
|
39
|
+
line.scan(/#{VALID_BEGINNING}(#{Regexp.escape(method_name)})\s*\("(.+?)"/) do |match|
|
40
|
+
add_translation(line_no, match[1], match[2], translations_found, yielder)
|
41
|
+
end
|
42
|
+
|
43
|
+
line.scan(/#{VALID_BEGINNING}(#{Regexp.escape(method_name)})\s*"(.+?)"/) do |match|
|
44
|
+
add_translation(line_no, match[1], match[2], translations_found, yielder)
|
45
|
+
end
|
46
|
+
|
47
|
+
line.scan(/#{VALID_BEGINNING}(#{Regexp.escape(method_name)})\s*\('(.+?)'/) do |match|
|
48
|
+
add_translation(line_no, match[1], match[2], translations_found, yielder)
|
49
|
+
end
|
50
|
+
|
51
|
+
line.scan(/#{VALID_BEGINNING}(#{Regexp.escape(method_name)})\s*'(.+?)'/) do |match|
|
52
|
+
add_translation(line_no, match[1], match[2], translations_found, yielder)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_translation(line_no, method, key, translations_found, yielder)
|
58
|
+
translation_inspector = AwesomeTranslations::ErbInspector::TranslationInspector.new(
|
59
|
+
root_path: @root_path,
|
60
|
+
file_path: @file_path,
|
61
|
+
line_no: line_no,
|
62
|
+
method: method,
|
63
|
+
key: key
|
64
|
+
)
|
65
|
+
|
66
|
+
unless translation_with_key_exists?(translations_found, translation_inspector.key)
|
67
|
+
yielder << translation_inspector
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def translation_with_key_exists?(translations_found, translation_key)
|
72
|
+
translations_found.select { |t| t.key == translation_key }.any?
|
73
|
+
end
|
74
|
+
|
75
|
+
def translation_key_from_dir_file_and_key(dir, file, key)
|
76
|
+
return key unless key.starts_with?(".")
|
77
|
+
|
78
|
+
file = file.gsub(/\A_/, "") # Remove partial indicator.
|
79
|
+
|
80
|
+
translation_key = dir
|
81
|
+
translation_key = translation_key.gsub(/\Aapp\//, "")
|
82
|
+
translation_key << "/#{file}"
|
83
|
+
translation_key.gsub!("/", ".")
|
84
|
+
translation_key << key
|
85
|
+
|
86
|
+
return translation_key
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
class AwesomeTranslations::ErbInspector::TranslationInspector
|
2
|
+
attr_reader :dir, :file_path, :line_no, :method, :key, :full_key, :full_path, :root_path
|
3
|
+
|
4
|
+
def initialize(args)
|
5
|
+
@dir, @file_path, @full_path, @line_no = args[:dir], args[:file_path], args[:full_path], args[:line_no]
|
6
|
+
@method, @key, @root_path = args[:method], args[:key], args[:root_path]
|
7
|
+
|
8
|
+
@full_path = "#{@root_path}/#{@file_path}"
|
9
|
+
|
10
|
+
generate_dir
|
11
|
+
generate_full_key
|
12
|
+
end
|
13
|
+
|
14
|
+
def model
|
15
|
+
AwesomeTranslations::Translation.new(
|
16
|
+
key: @full_key,
|
17
|
+
dir: @dir,
|
18
|
+
full_path: @full_path,
|
19
|
+
file_path: @file_path,
|
20
|
+
line_no: @line_no
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def generate_full_key
|
27
|
+
if @method == "t" && @key.start_with?(".")
|
28
|
+
@full_key = File.dirname(@file_path)
|
29
|
+
|
30
|
+
if @full_key.start_with?("app/views/")
|
31
|
+
# Remove "app/views" from view-translations since that doesn't get used in keys.
|
32
|
+
@full_key = @full_key.gsub(/\Aapp\/views\//, "")
|
33
|
+
elsif @full_key.start_with?("app/")
|
34
|
+
# Remove "app" from controller- and helper-translations since that doesn't get used.
|
35
|
+
@full_key = @full_key.gsub(/\Aapp\//, "")
|
36
|
+
end
|
37
|
+
|
38
|
+
@full_key = @full_key.gsub("/", ".")
|
39
|
+
@full_key << "."
|
40
|
+
@full_key << file_key(@file_path)
|
41
|
+
@full_key << "."
|
42
|
+
@full_key << @key.gsub(/\A\./, "")
|
43
|
+
elsif @method == "t"
|
44
|
+
@full_key = @key
|
45
|
+
else
|
46
|
+
raise "Unknown method-name: '#{@method}'."
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def file_key(file_path)
|
51
|
+
key = File.basename(file_path)
|
52
|
+
|
53
|
+
# Remove extension
|
54
|
+
key = key.match(/\A(.+?)\./)[1]
|
55
|
+
|
56
|
+
# Remove leading "_" from partials
|
57
|
+
key = key.gsub(/\A_/, "")
|
58
|
+
|
59
|
+
return key
|
60
|
+
end
|
61
|
+
|
62
|
+
def generate_dir
|
63
|
+
if @key.start_with?(".")
|
64
|
+
@dir = "#{Rails.root}/config/locales/awesome_translations/#{File.dirname(@file_path)}"
|
65
|
+
else
|
66
|
+
@dir = "#{Rails.root}/config/locales/awesome_translations"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class AwesomeTranslations::Handlers
|
2
|
+
@handlers = []
|
3
|
+
|
4
|
+
Dir.foreach("#{File.dirname(__FILE__)}/handlers") do |file|
|
5
|
+
match = file.match(/\A(.+)_handler\.rb\Z/)
|
6
|
+
next unless match
|
7
|
+
|
8
|
+
const_name_snake = "#{match[1]}_handler"
|
9
|
+
const_name_camel = StringCases.snake_to_camel(const_name_snake)
|
10
|
+
|
11
|
+
autoload const_name_camel.to_sym, "#{File.dirname(__FILE__)}/handlers/#{const_name_snake}"
|
12
|
+
|
13
|
+
unless const_name_snake == "base_handler"
|
14
|
+
@handlers << AwesomeTranslations::Handler.new(
|
15
|
+
id: const_name_snake,
|
16
|
+
const_name: const_name_camel,
|
17
|
+
name: const_name_camel
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.list
|
23
|
+
@handlers
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class AwesomeTranslations::Handlers::ErbHandler < AwesomeTranslations::Handlers::BaseHandler
|
2
|
+
METHOD_NAMES = ["_", "t"]
|
3
|
+
VALID_BEGINNING = '(^|\s+|\(|\{|<%=\s*)'
|
4
|
+
|
5
|
+
def groups
|
6
|
+
ArrayEnumerator.new do |yielder|
|
7
|
+
erb_inspector = AwesomeTranslations::ErbInspector.new
|
8
|
+
erb_inspector.files.each do |file|
|
9
|
+
yielder << AwesomeTranslations::Group.new(
|
10
|
+
id: Base64.urlsafe_encode64(file.full_path),
|
11
|
+
handler: self,
|
12
|
+
data: {
|
13
|
+
name: file.file_path,
|
14
|
+
root_path: file.root_path,
|
15
|
+
full_path: file.full_path
|
16
|
+
}
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def translations_for_group(group)
|
23
|
+
ArrayEnumerator.new do |yielder|
|
24
|
+
translations = []
|
25
|
+
|
26
|
+
# Parse views for translations.
|
27
|
+
erb_inspector = AwesomeTranslations::ErbInspector.new
|
28
|
+
file = erb_inspector.files.select { |file| file.full_path == group.data[:full_path] }.first
|
29
|
+
|
30
|
+
file.translations.each do |translation|
|
31
|
+
yielder << translation.model
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class AwesomeTranslations::Handlers::GlobalHandler < AwesomeTranslations::Handlers::BaseHandler
|
2
|
+
def groups
|
3
|
+
ArrayEnumerator.new do |yielder|
|
4
|
+
yielder << AwesomeTranslations::Group.new(
|
5
|
+
id: "global",
|
6
|
+
handler: self,
|
7
|
+
data: {
|
8
|
+
name: "Global translations"
|
9
|
+
}
|
10
|
+
)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def translations_for_group(group)
|
15
|
+
ArrayEnumerator.new do |yielder|
|
16
|
+
translations_found = {}
|
17
|
+
|
18
|
+
erb_inspector = AwesomeTranslations::ErbInspector.new
|
19
|
+
erb_inspector.files.each do |file|
|
20
|
+
file.translations.each do |translation|
|
21
|
+
next if translation.key.start_with?(".")
|
22
|
+
|
23
|
+
unless translations_found.key?(translation.full_key)
|
24
|
+
translations_found[translation.full_key] = true
|
25
|
+
yielder << translation.model
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
class AwesomeTranslations::Handlers::ModelHandler < AwesomeTranslations::Handlers::BaseHandler
|
2
|
+
def groups
|
3
|
+
ArrayEnumerator.new do |yielder|
|
4
|
+
AwesomeTranslations::ModelInspector.model_classes.each do |model_inspector|
|
5
|
+
yielder << AwesomeTranslations::Group.new(
|
6
|
+
id: model_inspector.clazz.name,
|
7
|
+
handler: self
|
8
|
+
)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def translations_for_group(group)
|
14
|
+
ArrayEnumerator.new do |yielder|
|
15
|
+
model_inspector = AwesomeTranslations::ModelInspector.model_classes.select { |model_inspector| model_inspector.clazz.name == group.name }.first
|
16
|
+
raise "No inspector by that name: #{model_inspector.clazz.name}" unless model_inspector
|
17
|
+
|
18
|
+
model_names(model_inspector).each { |translation| yielder << translation }
|
19
|
+
active_record_attributes(model_inspector).each { |translation| yielder << translation }
|
20
|
+
paperclip_attachments(model_inspector).each { |translation| yielder << translation }
|
21
|
+
relationships(model_inspector).each { |translation| yielder << translation }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def dir_path(model_inspector)
|
28
|
+
class_name = model_inspector.clazz.name
|
29
|
+
class_name = class_name.gsub("::", "_")
|
30
|
+
class_name = StringCases.camel_to_snake(class_name)
|
31
|
+
|
32
|
+
dir_path = "#{Rails.root}/config/locales/awesome_translations/models/#{class_name}"
|
33
|
+
|
34
|
+
return dir_path
|
35
|
+
end
|
36
|
+
|
37
|
+
def active_record_attributes(model_inspector)
|
38
|
+
result = []
|
39
|
+
|
40
|
+
model_inspector.attributes do |attribute|
|
41
|
+
translations = {}
|
42
|
+
|
43
|
+
I18n.available_locales.each do |locale|
|
44
|
+
translations[locale] = I18n.t(attribute.i18n_key, locale: locale)
|
45
|
+
end
|
46
|
+
|
47
|
+
result << AwesomeTranslations::Translation.new(
|
48
|
+
key: attribute.i18n_key,
|
49
|
+
dir: dir_path(model_inspector)
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
return result
|
54
|
+
end
|
55
|
+
|
56
|
+
def paperclip_attachments(model_inspector)
|
57
|
+
result = []
|
58
|
+
|
59
|
+
model_inspector.paperclip_attachments do |name|
|
60
|
+
result << AwesomeTranslations::Translation.new(
|
61
|
+
key: model_inspector.i18n_key(name),
|
62
|
+
dir: dir_path(model_inspector)
|
63
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
return result
|
67
|
+
end
|
68
|
+
|
69
|
+
def model_names(model_inspector)
|
70
|
+
result = []
|
71
|
+
result << AwesomeTranslations::Translation.new(
|
72
|
+
key: model_inspector.gettext_key_one,
|
73
|
+
dir: dir_path(model_inspector)
|
74
|
+
)
|
75
|
+
result << AwesomeTranslations::Translation.new(
|
76
|
+
key: model_inspector.gettext_key_other,
|
77
|
+
dir: dir_path(model_inspector)
|
78
|
+
)
|
79
|
+
|
80
|
+
return result
|
81
|
+
end
|
82
|
+
|
83
|
+
def relationships(model_inspector)
|
84
|
+
result = []
|
85
|
+
|
86
|
+
model_inspector.relationships do |key, reflection|
|
87
|
+
result << AwesomeTranslations::Translation.new(
|
88
|
+
key: model_inspector.i18n_key(reflection.name),
|
89
|
+
dir: dir_path(model_inspector)
|
90
|
+
)
|
91
|
+
end
|
92
|
+
|
93
|
+
return result
|
94
|
+
end
|
95
|
+
end
|