i18nline-rails 0.0.5.alpha
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 +7 -0
- data/Rakefile +34 -0
- data/app/assets/javascripts/i18nline/application.js +15 -0
- data/app/assets/javascripts/i18nline_to_host.js +7 -0
- data/app/assets/stylesheets/i18nline/_base.css +15 -0
- data/app/assets/stylesheets/i18nline/application.css +13 -0
- data/app/assets/stylesheets/i18nline_to_host.css +3 -0
- data/app/controllers/i18nline/application_controller.rb +13 -0
- data/app/controllers/i18nline/translations_controller.rb +95 -0
- data/app/helpers/i18nline/application_helper.rb +4 -0
- data/app/helpers/i18nline/translations_helper.rb +4 -0
- data/app/models/i18nline/translation.rb +55 -0
- data/app/views/i18nline/translations/_search_form.html.erb +26 -0
- data/app/views/i18nline/translations/edit_key.html.erb +56 -0
- data/app/views/i18nline/translations/index.html.erb +31 -0
- data/app/views/layouts/i18nline/application.html.erb +18 -0
- data/config/initializers/locale.rb +25 -0
- data/config/routes.rb +6 -0
- data/db/migrate/20131112155848_create_i18nline_translations.rb +18 -0
- data/lib/generators/i18nline/install_generator.rb +12 -0
- data/lib/generators/i18nline/templates/config/initializers/i18nline.rb +21 -0
- data/lib/i18nline.rb +29 -0
- data/lib/i18nline/action_view_extension.rb +40 -0
- data/lib/i18nline/engine.rb +5 -0
- data/lib/i18nline/railtie.rb +10 -0
- data/lib/i18nline/version.rb +3 -0
- data/lib/tasks/i18nline_tasks.rake +4 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/javascripts/hello.js +2 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/assets/stylesheets/hello.css +4 -0
- data/test/dummy/app/controllers/application_controller.rb +26 -0
- data/test/dummy/app/controllers/hello_controller.rb +11 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/hello_helper.rb +2 -0
- data/test/dummy/app/views/hello/hello.html.erb +11 -0
- data/test/dummy/app/views/layouts/application.html.erb +15 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +25 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/i18nline.rb +21 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +29 -0
- data/test/dummy/config/routes.rb +9 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +28 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +30666 -0
- data/test/dummy/log/test.log +17 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/test/helpers/hello_helper_test.rb +4 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/0f717e3c4863aa83b5ef697e89d0efa0 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/14a79238d484a545d971e3d941fe86e4 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/1fed974ece9b46e9543a13bd2cfd39c6 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/219e4ef52e71a2dd3142d36271626492 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/28cbea362ca86359d6a456435223469f +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/29331726baea36717bf28565c0be1881 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/29b9855933ef5ef7acb1d219e791dc2a +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/3c733f688711d6713374183251bc756e +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/4584795e7f513db14ffca10dab44759e +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/54cc037ce34a10f6cb709215e938d464 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/628fc32a4e0873a940ebf8a823e19ff7 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/637e3c52efb900d9d1a7e9be4606c8e0 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/68dc686a51587b32dfe7df0ed46af6e5 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/68ec19b2e986f843a7153c1c4e947469 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/72a227156d935c44e2aad8718b3952fb +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/75609286c4c1330bd547dae66258418b +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/8b4ee98cc6fbdab0922b4e98c2f95b4b +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/8c166e9c73eb969d1fffacccbebb7a28 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/8d41b05a7a0374a80a66fecb003b19fa +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/90b42249c96ca020cc4d4e5d209e3662 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/98cb4932cde5ab6aac080dfe2c1a666c +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/9bdaf3e65b045b8b71837f5662d72c5a +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/af81f90be8ad8a467e0198c5dae0bce6 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/b009f80f9687a780c4fab949cb1bcc60 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/bd646ad5989b27aa4beddd353406e7c2 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/c4f0ac344bd4304d32c569c9d1b50912 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/c50a18c681d1e0b8bdc1d2f4569776ca +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/c5d518b12d9d712aa81c6c98a57ad3b5 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/cfea650552ed221f83ea2c8fc3198c53 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/d3db0fcbbd3e669299cb370b3eba8a3f +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/e27275f4020fd1fc40de79a1e5db4c96 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/e5eea083daff4fcf6e9167de82c0ee77 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f0bca3bde3594952f22b26df6fea76a8 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/helpers/i18nline/translations_helper_test.rb +6 -0
- data/test/i18nline_test.rb +7 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- metadata +326 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 542c12dec29aa1727b2064c8eb6c99a2904e1467
|
|
4
|
+
data.tar.gz: 1f44fcafb0c33d17ab0d3481e52e17edaaab29db
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 59a57c01112dfe68f794773ebe6eaee7382e7b3fc0ad852277f9ea75f570dd3c5f686f20aa0458e051a5b177f3989d93995271f69deb4c8c45cfcb00b6835148
|
|
7
|
+
data.tar.gz: 72c68a8644094a82d2e04406f426f78da0147869977a84778c44df2b8153497a8f5be4ad5bf4e84c50a7b094f28ff8eade834d7e35b946912dd989590b03669f
|
data/Rakefile
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'bundler/setup'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
require 'rdoc/task'
|
|
8
|
+
|
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
11
|
+
rdoc.title = 'I18nline'
|
|
12
|
+
rdoc.options << '--line-numbers'
|
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
|
18
|
+
load 'rails/tasks/engine.rake'
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
Bundler::GemHelper.install_tasks
|
|
23
|
+
|
|
24
|
+
require 'rake/testtask'
|
|
25
|
+
|
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
|
27
|
+
t.libs << 'lib'
|
|
28
|
+
t.libs << 'test'
|
|
29
|
+
t.pattern = 'test/**/*_test.rb'
|
|
30
|
+
t.verbose = false
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
task default: :test
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
|
2
|
+
// listed below.
|
|
3
|
+
//
|
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
|
6
|
+
//
|
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
|
8
|
+
// compiled file.
|
|
9
|
+
//
|
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
|
11
|
+
// about supported directives.
|
|
12
|
+
//
|
|
13
|
+
//= require jquery
|
|
14
|
+
//= require jquery_ujs
|
|
15
|
+
//= require_tree .
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#edit_key_set .panel-danger{
|
|
2
|
+
background-color: #EED3D7;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
body {
|
|
6
|
+
font-size: 14px !important;
|
|
7
|
+
}
|
|
8
|
+
.form-control {
|
|
9
|
+
font-size: 14px !important;
|
|
10
|
+
height: 36px !important;
|
|
11
|
+
}
|
|
12
|
+
.btn {
|
|
13
|
+
padding: 6px 10px !important;
|
|
14
|
+
font-size: 14px !important;
|
|
15
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
+
* listed below.
|
|
4
|
+
*
|
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
|
7
|
+
*
|
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
|
10
|
+
*
|
|
11
|
+
*= require_self
|
|
12
|
+
*= require_tree .
|
|
13
|
+
*/
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module I18nline
|
|
2
|
+
class ApplicationController < ActionController::Base
|
|
3
|
+
before_action :check_authenticated_user
|
|
4
|
+
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def check_authenticated_user
|
|
8
|
+
unless(I18nline.current_user and I18nline.current_user.try(I18nline.can_translate_method))
|
|
9
|
+
redirect_to I18nline::login_route, error: "You need to login first"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require_dependency "i18nline/application_controller"
|
|
2
|
+
|
|
3
|
+
module I18nline
|
|
4
|
+
class TranslationsController < ApplicationController
|
|
5
|
+
before_action :set_translation, only: [:show, :edit, :update, :destroy]
|
|
6
|
+
|
|
7
|
+
def find_by_key
|
|
8
|
+
tokens = params[:key].split(".")
|
|
9
|
+
locale_at_inline_key = tokens.delete_at(0)
|
|
10
|
+
key = tokens.join(".")
|
|
11
|
+
translations = Translation.where("key = ?", key)
|
|
12
|
+
if translations.none?
|
|
13
|
+
redirect_to :root, error: "Something went wrong. No translations found." and return
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# This is needed to preserve nil values
|
|
17
|
+
# otherwise 'update action' receives ""
|
|
18
|
+
# and stores an empty string
|
|
19
|
+
translations.each do |a_tr|
|
|
20
|
+
if a_tr.value.nil?
|
|
21
|
+
a_tr.make_nil = true
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
require 'ostruct'
|
|
26
|
+
@tr_set = OpenStruct.new(
|
|
27
|
+
translations: translations,
|
|
28
|
+
key: key,
|
|
29
|
+
locale_at_inline_key: locale_at_inline_key,
|
|
30
|
+
interpolations: translations.first.interpolations.to_s,
|
|
31
|
+
is_proc: translations.first.is_proc
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
render "edit_key" and return
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# GET /translations
|
|
38
|
+
def index
|
|
39
|
+
q = Translation.search_key(params[:search_key])
|
|
40
|
+
.search_value(params[:search_value])
|
|
41
|
+
.in_locale(params[:search_locale])
|
|
42
|
+
.not_translated(params[:search_not_translated])
|
|
43
|
+
.blank_value(params[:search_blank_value])
|
|
44
|
+
@translations = q.page(params[:page]).per(25)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def update_key_set
|
|
48
|
+
unless params[:tr_set]
|
|
49
|
+
redirect_to :root, error: "Something went wrong. No translations found." and return
|
|
50
|
+
end
|
|
51
|
+
is_proc = params[:tr_set][:is_proc]
|
|
52
|
+
params[:tr_set][:translation].each do |translation|
|
|
53
|
+
db_translation = Translation.find(translation.first)
|
|
54
|
+
if db_translation
|
|
55
|
+
db_translation.value = translation.last[:value]
|
|
56
|
+
db_translation.is_proc = is_proc
|
|
57
|
+
if translation.last[:make_nil].presence == "1"
|
|
58
|
+
# it is likely that if value was nil and now is not, 'make_nil' has been left marked
|
|
59
|
+
# as a mistake, so in that case we ignore it and apply the new value:
|
|
60
|
+
unless db_translation.value_changed? and db_translation.value_was.nil?
|
|
61
|
+
db_translation.value = nil
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
if db_translation.changed?
|
|
65
|
+
db_translation.save
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
redirect_to :translations, notice: "Update successful."
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# PATCH/PUT /translations/1
|
|
73
|
+
def update
|
|
74
|
+
if translation_params[:make_nil].presence == "1"
|
|
75
|
+
params[:translation][:value] = nil
|
|
76
|
+
end
|
|
77
|
+
if @translation.update(translation_params)
|
|
78
|
+
redirect_to @translation, notice: 'Translation was successfully updated.'
|
|
79
|
+
else
|
|
80
|
+
render action: 'edit'
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
# Use callbacks to share common setup or constraints between actions.
|
|
86
|
+
def set_translation
|
|
87
|
+
@translation = Translation.find(params[:id])
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Only allow a trusted parameter "white list" through.
|
|
91
|
+
def translation_params
|
|
92
|
+
params.require(:translation).permit(:value, :is_proc, :make_nil)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module I18nline
|
|
2
|
+
class Translation < ActiveRecord::Base
|
|
3
|
+
after_save :update_caches
|
|
4
|
+
attr_accessor :make_nil
|
|
5
|
+
serialize :value
|
|
6
|
+
serialize :interpolations, Array
|
|
7
|
+
|
|
8
|
+
default_scope { order("created_at desc") }
|
|
9
|
+
|
|
10
|
+
def self.not_translated(apply_this = "1")
|
|
11
|
+
if apply_this.present?
|
|
12
|
+
where("value is null")
|
|
13
|
+
else
|
|
14
|
+
scoped
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.blank_value(apply_this = "1")
|
|
19
|
+
if apply_this.present?
|
|
20
|
+
#value is serialized so searching for empty is complicated:
|
|
21
|
+
where("value like ?", "".to_yaml)
|
|
22
|
+
else
|
|
23
|
+
scoped
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.in_locale(locale)
|
|
28
|
+
if locale.present?
|
|
29
|
+
where("locale = ?", locale)
|
|
30
|
+
else
|
|
31
|
+
scoped
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.search_key(to_search)
|
|
36
|
+
if to_search.present?
|
|
37
|
+
where("key like ?", "%#{to_search}%")
|
|
38
|
+
else
|
|
39
|
+
scoped
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.search_value(to_search)
|
|
44
|
+
if to_search.present?
|
|
45
|
+
where("value like ?", "%#{to_search}%")
|
|
46
|
+
else
|
|
47
|
+
scoped
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def update_caches
|
|
52
|
+
TRANSLATION_STORE.reload!
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<%= form_tag translations_path, :method => 'get', class: "form-inline", role: "form" do %>
|
|
2
|
+
<div class="form-group">
|
|
3
|
+
<label class="sr-only" for="search_key"> key:</label>
|
|
4
|
+
<%= text_field_tag :search_key, params[:search_key], class: "form-control", placeholder: "Search key" %>
|
|
5
|
+
</div>
|
|
6
|
+
<div class="form-group">
|
|
7
|
+
<label class="sr-only" for="search_value"> value:</label>
|
|
8
|
+
<%= text_field_tag :search_value, params[:search_value], class: "form-control", placeholder: "Search value" %>
|
|
9
|
+
</div>
|
|
10
|
+
<div class="form-group">
|
|
11
|
+
<%= select_tag :search_locale, options_for_select(I18nline::enabled_locales, params[:search_locale]), class: "form-control", prompt: "all locales" %>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="checkbox">
|
|
14
|
+
<label>
|
|
15
|
+
<%= check_box_tag :search_not_translated, "1", params[:search_not_translated] == "1" %>
|
|
16
|
+
Not translated
|
|
17
|
+
</label>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="checkbox">
|
|
20
|
+
<label>
|
|
21
|
+
<%= check_box_tag :search_blank_value, "1", params[:search_blank_value] == "1" %>
|
|
22
|
+
Has blank value
|
|
23
|
+
</label>
|
|
24
|
+
</div>
|
|
25
|
+
<%= submit_tag "Search", :name => nil, class: "btn btn-default" %>
|
|
26
|
+
<% end %>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<h1>Editing translation</h1>
|
|
2
|
+
|
|
3
|
+
<div id="edit_key_set" class="panel panel-default">
|
|
4
|
+
<div class="panel-heading">
|
|
5
|
+
<h3 class="panel-title">Key: <%= @tr_set.key %></h3>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="panel-body">
|
|
8
|
+
<%= form_for(@tr_set, as: :tr_set, url: update_key_set_path, method: :put, html: { class: 'form-horizontal', role: 'form' }) do |f| %>
|
|
9
|
+
<div class="form-group">
|
|
10
|
+
<label class="col-sm-2 control-label">Interpolations</label>
|
|
11
|
+
<div class="col-sm-10">
|
|
12
|
+
<%= f.text_field :interpolations, class: "form-control", disabled: :disabled %>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="form-group">
|
|
16
|
+
<div class="col-sm-offset-2 col-sm-10">
|
|
17
|
+
<div class="checkbox">
|
|
18
|
+
<label>
|
|
19
|
+
<%= f.check_box :is_proc %>
|
|
20
|
+
Is a proc?
|
|
21
|
+
</label>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
<% @tr_set.translations.each do |translation| %>
|
|
26
|
+
<% panel_color = translation.value.nil? ? "panel-danger" : "panel-info" %>
|
|
27
|
+
<div class="panel panel-default <%= panel_color %>">
|
|
28
|
+
<div class="panel-body">
|
|
29
|
+
<%= f.fields_for "translation[]", translation do |tl_form| %>
|
|
30
|
+
<div class="input-group col-sm-offset-2">
|
|
31
|
+
<span class="input-group-addon"><%= translation.locale %></span>
|
|
32
|
+
<% rows = (translation.value.to_s.length / 100) + 1 %>
|
|
33
|
+
<%= tl_form.text_area :value, class: "form-control", rows: "#{rows}" %>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="form-group">
|
|
36
|
+
<div class="col-sm-offset-2 col-sm-10">
|
|
37
|
+
<div class="checkbox">
|
|
38
|
+
<label>
|
|
39
|
+
<%= tl_form.check_box :make_nil %>
|
|
40
|
+
Make nil to cause missing_translation?
|
|
41
|
+
</label>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
<% end %>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
<% end %>
|
|
49
|
+
<div class="actions">
|
|
50
|
+
<%= f.submit "Save changes", class: "btn btn-primary" %>
|
|
51
|
+
<%= link_to 'Cancel', translations_path, class: "btn btn-default" %>
|
|
52
|
+
</div>
|
|
53
|
+
<% end %>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<h1>Listing translations</h1>
|
|
2
|
+
|
|
3
|
+
<%= render "search_form" %>
|
|
4
|
+
|
|
5
|
+
<table class="table table-hover">
|
|
6
|
+
<thead>
|
|
7
|
+
<tr>
|
|
8
|
+
<th>Locale</th>
|
|
9
|
+
<th>Key</th>
|
|
10
|
+
<th>Value</th>
|
|
11
|
+
<th>Modified at</th>
|
|
12
|
+
<th>Action</th>
|
|
13
|
+
</tr>
|
|
14
|
+
</thead>
|
|
15
|
+
|
|
16
|
+
<tbody>
|
|
17
|
+
<% @translations.each do |translation| %>
|
|
18
|
+
<% tr_color = translation.value.nil? ? "danger" : "" %>
|
|
19
|
+
<tr class="<%= tr_color %>">
|
|
20
|
+
<td><%= translation.locale %></td>
|
|
21
|
+
<td><%= translation.key %></td>
|
|
22
|
+
<td><%= translation.value.to_s.truncate(50) %></td>
|
|
23
|
+
<td class="date"><%= translation.updated_at.strftime("%T, %d %b %Y") %></td>
|
|
24
|
+
<td><%= link_to 'Edit', find_by_key_path(key: "#{translation.locale}.#{translation.key}") %></td>
|
|
25
|
+
</tr>
|
|
26
|
+
<% end %>
|
|
27
|
+
</tbody>
|
|
28
|
+
</table>
|
|
29
|
+
|
|
30
|
+
<%= paginate @translations %>
|
|
31
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>I18nline</title>
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<%= stylesheet_link_tag "i18nline/application", media: "all" %>
|
|
7
|
+
<%= javascript_include_tag "i18nline/application" %>
|
|
8
|
+
<%= stylesheet_link_tag "//netdna.bootstrapcdn.com/bootswatch/3.0.1/readable/bootstrap.min.css", media: "all" %>
|
|
9
|
+
<%= javascript_include_tag "//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" %>
|
|
10
|
+
<%= javascript_include_tag "//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js" %>
|
|
11
|
+
<%= csrf_meta_tags %>
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
<div class="container">
|
|
15
|
+
<%= yield %>
|
|
16
|
+
</div>
|
|
17
|
+
</body>
|
|
18
|
+
</html>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'i18n/backend/active_record'
|
|
2
|
+
module I18nline
|
|
3
|
+
class MyBackend < I18n::Backend::ActiveRecord
|
|
4
|
+
Translation.table_name = "i18nline_translations"
|
|
5
|
+
include I18n::Backend::ActiveRecord::Missing
|
|
6
|
+
include I18n::Backend::Memoize
|
|
7
|
+
|
|
8
|
+
def available_locales
|
|
9
|
+
I18nline::enabled_locales
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
TRANSLATION_STORE = I18nline::MyBackend.new
|
|
14
|
+
I18n.backend = I18n::Backend::Chain.new(TRANSLATION_STORE, I18n::Backend::Simple.new)
|
|
15
|
+
module I18n
|
|
16
|
+
class JustRaiseExceptionHandler < ExceptionHandler
|
|
17
|
+
def call(exception, locale, key, options)
|
|
18
|
+
if exception.is_a?(MissingTranslation)
|
|
19
|
+
TRANSLATION_STORE.store_default_translations(locale, key, options)
|
|
20
|
+
end
|
|
21
|
+
super
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
I18n.exception_handler = I18n::JustRaiseExceptionHandler.new
|