diff --git a/.ruby-version b/.ruby-version
index a4dd9dba..ef538c28 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-2.7.4
+3.1.2
diff --git a/Appraisals b/Appraisals
index 01263a2a..d9454a9c 100644
--- a/Appraisals
+++ b/Appraisals
@@ -1,7 +1,7 @@
-appraise 'rails-5.2' do
+appraise 'rails-7.0' do
source 'https://rubygems.org'
- gem 'rails', '~> 5.2.0'
- gem 'devise'
+ gem 'rails', '~> 7.0.4'
+ gem 'devise', '~> 4.8.1'
gem 'pg', '~> 1.2.3'
gem 'redis'
gem 'capybara'
@@ -16,47 +16,5 @@ appraise 'rails-5.2' do
gem 'rails-controller-testing'
gem 'minitest'
gem 'm', '~> 1.5.0'
- gem 'google-cloud-translate', '~> 1.2.4'
-end
-
-appraise 'rails-6.0' do
- source 'https://rubygems.org'
- gem 'rails', '~> 6.0.3'
- gem 'devise'
- gem 'pg', '~> 1.2.3'
- gem 'redis'
- gem 'capybara'
- gem 'database_cleaner'
- gem 'test_declarative'
- gem 'mocha'
- gem 'webmock'
- gem 'sass-rails'
- gem 'jquery-rails'
- gem 'coffee-rails'
- gem 'pry-rails'
- gem 'rails-controller-testing'
- gem 'minitest'
- gem 'm', '~> 1.5.0'
- gem 'google-cloud-translate', '~> 1.2.4'
-end
-
-appraise 'rails-6.1' do
- source 'https://rubygems.org'
- gem 'rails', '~> 6.1.4.1'
- gem 'devise'
- gem 'pg', '~> 1.2.3'
- gem 'redis'
- gem 'capybara'
- gem 'database_cleaner'
- gem 'test_declarative'
- gem 'mocha'
- gem 'webmock'
- gem 'sass-rails'
- gem 'jquery-rails'
- gem 'coffee-rails'
- gem 'pry-rails'
- gem 'rails-controller-testing'
- gem 'minitest'
- gem 'm', '~> 1.5.0'
- gem 'google-cloud-translate', '~> 2.1.2'
-end
+ gem "google-cloud-translate", "1.2.4"
+end
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 86e86ab4..73c33ad7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
## [Unreleased]
+- Support for Rails 7.0
## [WIP]
- Efforts to use Vanilla JS and remove jQuery [WIP]
diff --git a/README.md b/README.md
index 6552dcfa..ed8fefc0 100644
--- a/README.md
+++ b/README.md
@@ -102,7 +102,7 @@ $ rake lit:import FILE=stuff.csv LOCALES=en,pl SKIP_NIL=1
Additionally, there is the `lit:warm_up_keys` task (temporarily aliased as `lit:raw_import` for compatibility) which serves a different purpose: rather than for actual import of translations, it is intended to pre-load into database translations from a specific locale's YAML file **when the application is first deployed to a server and not all translation keys are present in the database yet**. This task also takes the `SKIP_NIL` option in a similar way as the import task.
```bash
-$ rake lit:warm_up_keys FILES=config/locales/en.yml LOCALES=en
+$ rake lit:warm_up_keys FILES=en.yml LOCALE=en
```
In this case, when the `config/locales/en.yml` contains a translation for `foo` which doesn't have a key in the DB yet, it will be created, but if it already exists in the DB with a translation, it won't be overridden.
@@ -122,6 +122,24 @@ Currently, Google and Yandex translation providers are supported, but extending
Configure your translation provider using one of routines described below. When a translation provider is configured, each localization in Lit web UI will have a "Translate using _Provider Name_" button next to it, which by default translates to the localization's language from the localization currently saved for the app's `I18n.default_locale`.
Next to the button, there is a dropdown that allows translating from the key's localization in a language different than the default one.
+#### DeepL Cloud Translation API
+
+Insert this into your Lit initializer:
+```
+require 'lit/cloud_translation/providers/deepl_translator'
+
+Lit::CloudTranslation.provider = Lit::CloudTranslation::Providers::DeeplTranslator
+Lit::CloudTranslation.configure do |config|
+ config.api_key = HashWithIndifferentAccess.new(Rails.application.credentials.config[:deepl_api])
+end
+```
+
+...and make sure you have this in your Gemfile:
+
+```
+gem "deepl-rb", require: "deepl"
+```
+
#### Google Cloud Translation API
Insert this into your Lit initializer:
@@ -296,7 +314,7 @@ Lit.store_request_keys = true
1. `gem install bundler && bundle install` - ensure Bundler and all required gems are installed
2. `bundle exec appraisal install` - install gems from appraisal's gemfiles
3. `cp test/dummy/config/database.yml.sample test/dummy/config/database.yml` - move a database.yml in place (remember to fill your DB credentials in it)
-4. `RAILS_ENV=test bundle exec appraisal rails-5.2 rake db:setup` - setup lit DB (see test/config/database.yml); do it
+4. `RAILS_ENV=test bundle exec appraisal rails-7.0 rake db:setup` - setup lit DB (see test/config/database.yml); do it
only once, it does not matter which Rails version you use for `appraisal`
5. `bundle exec appraisal rake` - run the tests!
diff --git a/app/controllers/lit/api/v1/base_controller.rb b/app/controllers/lit/api/v1/base_lit_controller.rb
similarity index 74%
rename from app/controllers/lit/api/v1/base_controller.rb
rename to app/controllers/lit/api/v1/base_lit_controller.rb
index 212b7993..d557783c 100644
--- a/app/controllers/lit/api/v1/base_controller.rb
+++ b/app/controllers/lit/api/v1/base_lit_controller.rb
@@ -1,9 +1,8 @@
module Lit
module Api
module V1
- class BaseController < ActionController::Base
+ class BaseLitController < ActionController::Base
layout nil
- respond_to :json if ::Rails::VERSION::MAJOR < 5
before_action :authenticate_requests!
private
diff --git a/app/controllers/lit/api/v1/locales_controller.rb b/app/controllers/lit/api/v1/locales_controller.rb
index bddb2917..8a78abee 100644
--- a/app/controllers/lit/api/v1/locales_controller.rb
+++ b/app/controllers/lit/api/v1/locales_controller.rb
@@ -1,12 +1,12 @@
-require_dependency 'lit/api/v1/base_controller'
+require_dependency 'lit/api/v1/base_lit_controller'
module Lit
module Api
module V1
- class LocalesController < Api::V1::BaseController
+ class LocalesController < Api::V1::BaseLitController
def index
@locales = Locale.all
- render json: @locales.as_json(root: false, only: %i[id locale])
+ render json: @locales.as_json(root: false, only: %i[id locale]).to_json
end
end
end
diff --git a/app/controllers/lit/api/v1/localization_keys_controller.rb b/app/controllers/lit/api/v1/localization_keys_controller.rb
index bea8b422..fb4ce729 100644
--- a/app/controllers/lit/api/v1/localization_keys_controller.rb
+++ b/app/controllers/lit/api/v1/localization_keys_controller.rb
@@ -1,12 +1,12 @@
-require_dependency 'lit/api/v1/base_controller'
+require_dependency 'lit/api/v1/base_lit_controller'
module Lit
- class Api::V1::LocalizationKeysController < Api::V1::BaseController
+ class Api::V1::LocalizationKeysController < Api::V1::BaseLitController
def index
@localization_keys = fetch_localization_keys
render json: @localization_keys.as_json(
root: false, only: %i[id localization_key is_deleted]
- )
+ ).to_json
end
private
diff --git a/app/controllers/lit/api/v1/localizations_controller.rb b/app/controllers/lit/api/v1/localizations_controller.rb
index c121449a..5abc9df4 100644
--- a/app/controllers/lit/api/v1/localizations_controller.rb
+++ b/app/controllers/lit/api/v1/localizations_controller.rb
@@ -1,5 +1,5 @@
module Lit
- class Api::V1::LocalizationsController < Api::V1::BaseController
+ class Api::V1::LocalizationsController < Api::V1::BaseLitController
def index
@localizations = fetch_localizations
render json:
@@ -7,7 +7,7 @@ def index
root: false,
only: %i[id localization_key_id locale_id],
methods: %i[value localization_key_str locale_str localization_key_is_deleted],
- )
+ ).to_json
end
def last_change
diff --git a/app/models/lit/incomming_localization.rb b/app/models/lit/incomming_localization.rb
index e244fb46..d2418b3b 100644
--- a/app/models/lit/incomming_localization.rb
+++ b/app/models/lit/incomming_localization.rb
@@ -76,6 +76,8 @@ def assign_new_localization_key
end
def assign_new_localization
+ create_other_localizations if localization_key.localizations.blank?
+
self.localization =
Lit::Localization
.where(localization_key_id: localization_key.id)
@@ -86,6 +88,19 @@ def assign_new_localization
localization.save!
end
+ def create_other_localizations
+ ::Lit::Locale.where.not(id: locale.id).pluck(:id).each do |locale_id|
+ localization =
+ Lit::Localization
+ .where(localization_key_id: localization_key.id)
+ .where(locale_id: locale_id)
+ .first_or_initialize
+ localization.translated_value = translated_value
+ localization.save!
+ Lit.init.cache.update_cache localization.full_key, localization.translation
+ end
+ end
+
def update_cache
Lit.init.cache.update_cache localization.full_key, localization.translation
end
diff --git a/app/models/lit/localization.rb b/app/models/lit/localization.rb
index e1659fd4..b3dc66c6 100644
--- a/app/models/lit/localization.rb
+++ b/app/models/lit/localization.rb
@@ -23,6 +23,8 @@ class Localization < Lit::Base
## VALIDATIONS
validates :locale, :localization_key, presence: true
+ validate :correct_interpolation_keys
+
## ACCESSORS
attr_accessor :full_key_str
@@ -63,7 +65,7 @@ def locale_str
end
def last_change
- updated_at.to_s(:db)
+ updated_at.to_fs(:db)
end
def update_default_value(value)
@@ -87,5 +89,30 @@ def create_version
translated_value = translated_value_was || default_value
localization_versions.new(translated_value: translated_value)
end
+
+ def correct_interpolation_keys
+ return if locale_str == "en"
+
+ english_translation = find_english_translation
+ return unless english_translation
+
+ english_interpolation_keys = interpolation_keys(english_translation.translation)
+ interpolation_keys = interpolation_keys(self.translated_value)
+ if interpolation_keys != english_interpolation_keys
+ errors.add(:base, "Interpolation keys do not match: please do not touch variables such as: %{example}.")
+ end
+ end
+
+ def find_english_translation
+ self.class.joins(:locale, :localization_key).find_by(localization_key: { localization_key: self.localization_key_str }, locale: { locale: "en" })
+ end
+
+ def interpolation_keys(text)
+ return [] unless text
+
+ keys = []
+ text % Hash.new { |_, k| keys << k ; 0 }
+ keys
+ end
end
end
diff --git a/app/services/synchronize_source_service.rb b/app/services/synchronize_source_service.rb
index 8a12faff..1f96d202 100644
--- a/app/services/synchronize_source_service.rb
+++ b/app/services/synchronize_source_service.rb
@@ -1,6 +1,7 @@
class SynchronizeSourceService
- def initialize(source)
+ def initialize(source, auto_accept = false)
@source = source
+ @auto_accept = auto_accept
end
def execute
@@ -11,7 +12,7 @@ def execute
private
def synchronize_localizations
- after_date = @source.last_updated_at&.to_s(:db)
+ after_date = @source.last_updated_at&.to_fs(:db)
result = interactor.send_request Lit::Source::LOCALIZATIONS_PATH, after: after_date
return unless result&.is_a?(Array)
result.each { |loc| synchronize_localization loc }
@@ -29,6 +30,7 @@ def synchronize_localization(loc)
return if inc_loc.duplicated?(loc['value'])
inc_loc.save!
+ inc_loc.accept if @auto_accept
end
def find_incomming_localization(localization)
diff --git a/app/views/layouts/lit/application.html.erb b/app/views/layouts/lit/application.html.erb
index 9b226ca9..e0a69b63 100644
--- a/app/views/layouts/lit/application.html.erb
+++ b/app/views/layouts/lit/application.html.erb
@@ -5,9 +5,9 @@
- <%= stylesheet_link_tag '//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css', media: 'all' %>
- <%= stylesheet_link_tag '//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', media: 'all' %>
- <%= stylesheet_link_tag '//netdna.bootstrapcdn.com/bootswatch/3.0.3/yeti/bootstrap.min.css', media: 'all' %>
+ <%= stylesheet_link_tag 'https://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css', media: 'all' %>
+ <%= stylesheet_link_tag 'https://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', media: 'all' %>
+ <%= stylesheet_link_tag 'https://netdna.bootstrapcdn.com/bootswatch/3.0.3/yeti/bootstrap.min.css', media: 'all' %>
<%= stylesheet_link_tag 'lit/application', media: 'all' %>
<%= javascript_include_tag 'lit/application' %>
<%= csrf_meta_tags %>
@@ -33,13 +33,6 @@
<% end %>
-