i18nline 0.0.2.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.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +34 -0
  3. data/app/assets/javascripts/i18nline/application.js +15 -0
  4. data/app/assets/javascripts/i18nline_to_host.js +7 -0
  5. data/app/assets/stylesheets/i18nline/_base.css +15 -0
  6. data/app/assets/stylesheets/i18nline/application.css +13 -0
  7. data/app/assets/stylesheets/i18nline_to_host.css +3 -0
  8. data/app/controllers/i18nline/application_controller.rb +13 -0
  9. data/app/controllers/i18nline/translations_controller.rb +95 -0
  10. data/app/helpers/i18nline/application_helper.rb +4 -0
  11. data/app/helpers/i18nline/translations_helper.rb +4 -0
  12. data/app/models/i18nline/translation.rb +55 -0
  13. data/app/views/i18nline/translations/_search_form.html.erb +26 -0
  14. data/app/views/i18nline/translations/edit_key.html.erb +56 -0
  15. data/app/views/i18nline/translations/index.html.erb +31 -0
  16. data/app/views/layouts/i18nline/application.html.erb +18 -0
  17. data/config/initializers/kaminari_config.rb +10 -0
  18. data/config/initializers/locale.rb +25 -0
  19. data/config/routes.rb +6 -0
  20. data/db/migrate/20131112155848_create_i18nline_translations.rb +18 -0
  21. data/lib/generators/i18nline/install_generator.rb +12 -0
  22. data/lib/generators/i18nline/templates/config/initializers/i18nline.rb +21 -0
  23. data/lib/i18nline/action_view_extension.rb +40 -0
  24. data/lib/i18nline/engine.rb +5 -0
  25. data/lib/i18nline/railtie.rb +10 -0
  26. data/lib/i18nline/version.rb +3 -0
  27. data/lib/i18nline.rb +28 -0
  28. data/lib/tasks/i18nline_tasks.rake +4 -0
  29. data/test/dummy/README.rdoc +28 -0
  30. data/test/dummy/Rakefile +6 -0
  31. data/test/dummy/app/assets/javascripts/application.js +15 -0
  32. data/test/dummy/app/assets/javascripts/hello.js +2 -0
  33. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  34. data/test/dummy/app/assets/stylesheets/hello.css +4 -0
  35. data/test/dummy/app/controllers/application_controller.rb +26 -0
  36. data/test/dummy/app/controllers/hello_controller.rb +11 -0
  37. data/test/dummy/app/helpers/application_helper.rb +2 -0
  38. data/test/dummy/app/helpers/hello_helper.rb +2 -0
  39. data/test/dummy/app/views/hello/hello.html.erb +11 -0
  40. data/test/dummy/app/views/layouts/application.html.erb +15 -0
  41. data/test/dummy/bin/bundle +3 -0
  42. data/test/dummy/bin/rails +4 -0
  43. data/test/dummy/bin/rake +4 -0
  44. data/test/dummy/config/application.rb +23 -0
  45. data/test/dummy/config/boot.rb +5 -0
  46. data/test/dummy/config/database.yml +25 -0
  47. data/test/dummy/config/environment.rb +5 -0
  48. data/test/dummy/config/environments/development.rb +29 -0
  49. data/test/dummy/config/environments/production.rb +80 -0
  50. data/test/dummy/config/environments/test.rb +36 -0
  51. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  52. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  53. data/test/dummy/config/initializers/i18nline.rb +21 -0
  54. data/test/dummy/config/initializers/inflections.rb +16 -0
  55. data/test/dummy/config/initializers/mime_types.rb +5 -0
  56. data/test/dummy/config/initializers/secret_token.rb +12 -0
  57. data/test/dummy/config/initializers/session_store.rb +3 -0
  58. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  59. data/test/dummy/config/locales/en.yml +29 -0
  60. data/test/dummy/config/routes.rb +9 -0
  61. data/test/dummy/config.ru +4 -0
  62. data/test/dummy/db/development.sqlite3 +0 -0
  63. data/test/dummy/db/schema.rb +28 -0
  64. data/test/dummy/db/test.sqlite3 +0 -0
  65. data/test/dummy/log/development.log +30443 -0
  66. data/test/dummy/log/test.log +17 -0
  67. data/test/dummy/public/404.html +58 -0
  68. data/test/dummy/public/422.html +58 -0
  69. data/test/dummy/public/500.html +57 -0
  70. data/test/dummy/public/favicon.ico +0 -0
  71. data/test/dummy/test/helpers/hello_helper_test.rb +4 -0
  72. data/test/dummy/tmp/cache/assets/development/sprockets/0f717e3c4863aa83b5ef697e89d0efa0 +0 -0
  73. data/test/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  74. data/test/dummy/tmp/cache/assets/development/sprockets/14a79238d484a545d971e3d941fe86e4 +0 -0
  75. data/test/dummy/tmp/cache/assets/development/sprockets/1fed974ece9b46e9543a13bd2cfd39c6 +0 -0
  76. data/test/dummy/tmp/cache/assets/development/sprockets/219e4ef52e71a2dd3142d36271626492 +0 -0
  77. data/test/dummy/tmp/cache/assets/development/sprockets/28cbea362ca86359d6a456435223469f +0 -0
  78. data/test/dummy/tmp/cache/assets/development/sprockets/29331726baea36717bf28565c0be1881 +0 -0
  79. data/test/dummy/tmp/cache/assets/development/sprockets/29b9855933ef5ef7acb1d219e791dc2a +0 -0
  80. data/test/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  81. data/test/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  82. data/test/dummy/tmp/cache/assets/development/sprockets/3c733f688711d6713374183251bc756e +0 -0
  83. data/test/dummy/tmp/cache/assets/development/sprockets/4584795e7f513db14ffca10dab44759e +0 -0
  84. data/test/dummy/tmp/cache/assets/development/sprockets/54cc037ce34a10f6cb709215e938d464 +0 -0
  85. data/test/dummy/tmp/cache/assets/development/sprockets/628fc32a4e0873a940ebf8a823e19ff7 +0 -0
  86. data/test/dummy/tmp/cache/assets/development/sprockets/637e3c52efb900d9d1a7e9be4606c8e0 +0 -0
  87. data/test/dummy/tmp/cache/assets/development/sprockets/68dc686a51587b32dfe7df0ed46af6e5 +0 -0
  88. data/test/dummy/tmp/cache/assets/development/sprockets/68ec19b2e986f843a7153c1c4e947469 +0 -0
  89. data/test/dummy/tmp/cache/assets/development/sprockets/72a227156d935c44e2aad8718b3952fb +0 -0
  90. data/test/dummy/tmp/cache/assets/development/sprockets/75609286c4c1330bd547dae66258418b +0 -0
  91. data/test/dummy/tmp/cache/assets/development/sprockets/8b4ee98cc6fbdab0922b4e98c2f95b4b +0 -0
  92. data/test/dummy/tmp/cache/assets/development/sprockets/8c166e9c73eb969d1fffacccbebb7a28 +0 -0
  93. data/test/dummy/tmp/cache/assets/development/sprockets/8d41b05a7a0374a80a66fecb003b19fa +0 -0
  94. data/test/dummy/tmp/cache/assets/development/sprockets/90b42249c96ca020cc4d4e5d209e3662 +0 -0
  95. data/test/dummy/tmp/cache/assets/development/sprockets/98cb4932cde5ab6aac080dfe2c1a666c +0 -0
  96. data/test/dummy/tmp/cache/assets/development/sprockets/9bdaf3e65b045b8b71837f5662d72c5a +0 -0
  97. data/test/dummy/tmp/cache/assets/development/sprockets/af81f90be8ad8a467e0198c5dae0bce6 +0 -0
  98. data/test/dummy/tmp/cache/assets/development/sprockets/b009f80f9687a780c4fab949cb1bcc60 +0 -0
  99. data/test/dummy/tmp/cache/assets/development/sprockets/bd646ad5989b27aa4beddd353406e7c2 +0 -0
  100. data/test/dummy/tmp/cache/assets/development/sprockets/c4f0ac344bd4304d32c569c9d1b50912 +0 -0
  101. data/test/dummy/tmp/cache/assets/development/sprockets/c50a18c681d1e0b8bdc1d2f4569776ca +0 -0
  102. data/test/dummy/tmp/cache/assets/development/sprockets/c5d518b12d9d712aa81c6c98a57ad3b5 +0 -0
  103. data/test/dummy/tmp/cache/assets/development/sprockets/cfea650552ed221f83ea2c8fc3198c53 +0 -0
  104. data/test/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  105. data/test/dummy/tmp/cache/assets/development/sprockets/d3db0fcbbd3e669299cb370b3eba8a3f +0 -0
  106. data/test/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  107. data/test/dummy/tmp/cache/assets/development/sprockets/e27275f4020fd1fc40de79a1e5db4c96 +0 -0
  108. data/test/dummy/tmp/cache/assets/development/sprockets/e5eea083daff4fcf6e9167de82c0ee77 +0 -0
  109. data/test/dummy/tmp/cache/assets/development/sprockets/f0bca3bde3594952f22b26df6fea76a8 +0 -0
  110. data/test/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  111. data/test/helpers/i18nline/translations_helper_test.rb +6 -0
  112. data/test/i18nline_test.rb +7 -0
  113. data/test/integration/navigation_test.rb +10 -0
  114. data/test/test_helper.rb +15 -0
  115. metadata +313 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9735908d64a162fd6609bad31eeff6eb39c8f4fe
4
+ data.tar.gz: d220b2d3f964c7b9bb7b3687807f55c6fbf6969a
5
+ SHA512:
6
+ metadata.gz: 21507271b19bc58d5f1e6ce01ef3b2a87ad466a662d45efa65fdb3253b467ec48c25e917a9d9ce87f5cae424a966f29736ead8b59b2182f1d69cae62348d647e
7
+ data.tar.gz: 6975c6965347bc646affd6aa9fc578dd479b2c4ec210e143fe178e441d6c7a739759eb4d26127edb184325318839ae4b56f5b1fdf1b53012ba0078948e0eb57a
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,7 @@
1
+ $(document).ready(function() {
2
+ $('span.translation_missing').contextmenu(function(event) {
3
+ key = $(this).attr("title").split(":")[1].trim()
4
+ window.open("/i18nline/find_by_key?key=" + key, "_blank");
5
+ return false; //prevent context menu to show
6
+ });
7
+ });
@@ -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,3 @@
1
+ span.translation_missing {
2
+ border-bottom: 2px solid red;
3
+ }
@@ -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,4 @@
1
+ module I18nline
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module I18nline
2
+ module TranslationsHelper
3
+ end
4
+ 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,10 @@
1
+ Kaminari.configure do |config|
2
+ # config.default_per_page = 25
3
+ # config.max_per_page = nil
4
+ # config.window = 4
5
+ # config.outer_window = 0
6
+ # config.left = 0
7
+ # config.right = 0
8
+ # config.page_method_name = :page
9
+ # config.param_name = :page
10
+ end
@@ -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
data/config/routes.rb ADDED
@@ -0,0 +1,6 @@
1
+ I18nline::Engine.routes.draw do
2
+ resources :translations
3
+ get "find_by_key", to: "translations#find_by_key"
4
+ put "update_key_set", to: "translations#update_key_set"
5
+ root to: "translations#index"
6
+ end
@@ -0,0 +1,18 @@
1
+ class CreateI18nlineTranslations < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :i18nline_translations do |t|
4
+ t.string :locale
5
+ t.string :key
6
+ t.text :value
7
+ t.text :interpolations
8
+ t.boolean :is_proc, :default => false
9
+
10
+ t.timestamps
11
+ end
12
+ add_index :i18nline_translations, [:locale, :key], unique: true
13
+ end
14
+
15
+ def self.down
16
+ drop_table :i18nline_translations
17
+ end
18
+ end
@@ -0,0 +1,12 @@
1
+ module I18nline
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ desc "Copy i18nline default files"
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ def copy_config
8
+ template "config/initializers/i18nline.rb"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ # Use this setup block to configure all options available in i18nline.
2
+ I18nline.setup do |config|
3
+
4
+ # A helper method available in your views so we can ask if there is a current user.
5
+ #config.current_user_method = "current_user"
6
+
7
+ # A method your current_user has to respond to affirmatively to be able to
8
+ # interact with i18nline administration features, like inline markers and
9
+ # translation management views.
10
+ # This method will be tried in the instance returned by the 'current_user' helper
11
+ # specified above: current_user.can_translate?
12
+ #config.can_translate_method = "can_translate?"
13
+
14
+ # A route available in your application to redirect the user to login
15
+ # when he tries to access to protected views. This route should be
16
+ # available on your 'rake routes'.
17
+ #config.login_route = "\login_url"
18
+
19
+ # Missing translations will be generated for this locales.
20
+ #config.enabled_locales = %w(en es it)
21
+ end
@@ -0,0 +1,40 @@
1
+ module I18nline
2
+ module ActionViewExtension
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ def current_user_can_translate?
7
+ current_user = send I18nline.current_user_method
8
+ if current_user
9
+ if current_user.try I18nline.can_translate_method
10
+ I18nline.current_user = current_user
11
+ return true
12
+ end
13
+ end
14
+ false
15
+ end
16
+ end
17
+
18
+ def i18nline_assets_inclusion_tag
19
+ if current_user_can_translate?
20
+ assets = ""
21
+ assets << i18nline_host_styles << "\n"
22
+ assets << i18nline_host_javascripts << "\n"
23
+ assets.html_safe
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ # Javascripts that will be loaded on host application:
30
+ def i18nline_host_javascripts
31
+ javascript_include_tag("i18nline_to_host.js")
32
+ end
33
+
34
+ # Css that will be loaded on host application:
35
+ def i18nline_host_styles
36
+ stylesheet_link_tag("i18nline_to_host.css")
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,5 @@
1
+ module I18nline
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace I18nline
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ require File.join(File.dirname(__FILE__), 'action_view_extension')
2
+ module I18nline
3
+ class Railtie < Rails::Railtie
4
+ initializer "i18nline.configure_rails_initialization" do
5
+ ActiveSupport.on_load(:action_view) do
6
+ ::ActionView::Base.send :include, I18nline::ActionViewExtension
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module I18nline
2
+ VERSION = "0.0.2.alpha"
3
+ end
data/lib/i18nline.rb ADDED
@@ -0,0 +1,28 @@
1
+ require "i18nline/engine"
2
+ require 'i18nline/railtie' if defined?(Rails)
3
+
4
+ module I18nline
5
+
6
+ ## CONFIGURATION OPTIONS:
7
+
8
+ mattr_accessor :current_user_method
9
+ @@current_user_method = "current_user"
10
+
11
+ mattr_accessor :can_translate_method
12
+ @@can_translate_method = "can_translate?"
13
+
14
+ mattr_accessor :login_route
15
+ @@login_route = "/login"
16
+
17
+ mattr_accessor :enabled_locales
18
+ @@enabled_locales = %w(en es it)
19
+
20
+ def self.setup
21
+ yield self
22
+ end
23
+
24
+ private
25
+ mattr_accessor :current_user
26
+ @@current_user ||= nil
27
+
28
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :i18nline do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Dummy::Application.load_tasks