phraseapp-in-context-editor-ruby 2.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +18 -0
- data/.github/workflows/close_inactive_issues.yml +18 -0
- data/.github/workflows/release.yml +28 -0
- data/.github/workflows/test.yml +6 -3
- data/.gitignore +1 -0
- data/CHANGELOG.md +22 -87
- data/CODEOWNERS +1 -1
- data/Gemfile.lock +4 -1
- data/RELEASING.md +2 -9
- data/docs/CHANGELOG.md +116 -0
- data/examples/demo/.gitattributes +7 -0
- data/examples/demo/.gitignore +35 -0
- data/examples/demo/Gemfile +74 -0
- data/examples/demo/Gemfile.lock +268 -0
- data/examples/demo/README.md +5 -0
- data/examples/demo/Rakefile +6 -0
- data/examples/demo/app/assets/config/manifest.js +4 -0
- data/examples/demo/app/assets/images/.keep +0 -0
- data/examples/demo/app/assets/stylesheets/application.css +15 -0
- data/examples/demo/app/channels/application_cable/channel.rb +4 -0
- data/examples/demo/app/channels/application_cable/connection.rb +4 -0
- data/examples/demo/app/controllers/application_controller.rb +2 -0
- data/examples/demo/app/controllers/concerns/.keep +0 -0
- data/examples/demo/app/controllers/main_controller.rb +4 -0
- data/examples/demo/app/helpers/application_helper.rb +2 -0
- data/examples/demo/app/helpers/main_helper.rb +2 -0
- data/examples/demo/app/javascript/application.js +3 -0
- data/examples/demo/app/javascript/controllers/application.js +9 -0
- data/examples/demo/app/javascript/controllers/hello_controller.js +7 -0
- data/examples/demo/app/javascript/controllers/index.js +11 -0
- data/examples/demo/app/jobs/application_job.rb +7 -0
- data/examples/demo/app/mailers/application_mailer.rb +4 -0
- data/examples/demo/app/models/application_record.rb +3 -0
- data/examples/demo/app/models/concerns/.keep +0 -0
- data/examples/demo/app/views/layouts/application.html.erb +17 -0
- data/examples/demo/app/views/layouts/mailer.html.erb +13 -0
- data/examples/demo/app/views/layouts/mailer.text.erb +1 -0
- data/examples/demo/app/views/main/index.html.erb +8 -0
- data/examples/demo/bin/bundle +109 -0
- data/examples/demo/bin/importmap +4 -0
- data/examples/demo/bin/rails +4 -0
- data/examples/demo/bin/rake +4 -0
- data/examples/demo/bin/setup +33 -0
- data/examples/demo/config/application.rb +22 -0
- data/examples/demo/config/boot.rb +4 -0
- data/examples/demo/config/cable.yml +10 -0
- data/examples/demo/config/credentials.yml.enc +1 -0
- data/examples/demo/config/database.yml +25 -0
- data/examples/demo/config/environment.rb +5 -0
- data/examples/demo/config/environments/development.rb +70 -0
- data/examples/demo/config/environments/production.rb +93 -0
- data/examples/demo/config/environments/test.rb +60 -0
- data/examples/demo/config/importmap.rb +7 -0
- data/examples/demo/config/initializers/assets.rb +12 -0
- data/examples/demo/config/initializers/content_security_policy.rb +25 -0
- data/examples/demo/config/initializers/filter_parameter_logging.rb +8 -0
- data/examples/demo/config/initializers/inflections.rb +16 -0
- data/examples/demo/config/initializers/permissions_policy.rb +11 -0
- data/examples/demo/config/initializers/phraseapp_in_context_editor.rb +20 -0
- data/examples/demo/config/locales/en.yml +38 -0
- data/examples/demo/config/puma.rb +43 -0
- data/examples/demo/config/routes.rb +6 -0
- data/examples/demo/config/storage.yml +34 -0
- data/examples/demo/config.ru +6 -0
- data/examples/demo/db/seeds.rb +7 -0
- data/examples/demo/lib/assets/.keep +0 -0
- data/examples/demo/lib/tasks/.keep +0 -0
- data/examples/demo/log/.keep +0 -0
- data/examples/demo/public/404.html +67 -0
- data/examples/demo/public/422.html +67 -0
- data/examples/demo/public/500.html +66 -0
- data/examples/demo/public/apple-touch-icon-precomposed.png +0 -0
- data/examples/demo/public/apple-touch-icon.png +0 -0
- data/examples/demo/public/favicon.ico +0 -0
- data/examples/demo/public/robots.txt +1 -0
- data/examples/demo/storage/.keep +0 -0
- data/examples/demo/test/application_system_test_case.rb +5 -0
- data/examples/demo/test/channels/application_cable/connection_test.rb +11 -0
- data/examples/demo/test/controllers/.keep +0 -0
- data/examples/demo/test/controllers/main_controller_test.rb +8 -0
- data/examples/demo/test/fixtures/files/.keep +0 -0
- data/examples/demo/test/helpers/.keep +0 -0
- data/examples/demo/test/integration/.keep +0 -0
- data/examples/demo/test/mailers/.keep +0 -0
- data/examples/demo/test/models/.keep +0 -0
- data/examples/demo/test/system/.keep +0 -0
- data/examples/demo/test/test_helper.rb +13 -0
- data/examples/demo/tmp/.keep +0 -0
- data/examples/demo/tmp/pids/.keep +0 -0
- data/examples/demo/tmp/storage/.keep +0 -0
- data/examples/demo/vendor/.keep +0 -0
- data/examples/demo/vendor/javascript/.keep +0 -0
- data/lib/generators/phraseapp_in_context_editor/templates/phraseapp_in_context_editor.rb +4 -0
- data/lib/phraseapp-in-context-editor-ruby/adapters/i18n.rb +2 -2
- data/lib/phraseapp-in-context-editor-ruby/backend_service.rb +16 -31
- data/lib/phraseapp-in-context-editor-ruby/config.rb +3 -1
- data/lib/phraseapp-in-context-editor-ruby/delegate/i18n_delegate.rb +2 -2
- data/lib/phraseapp-in-context-editor-ruby/version.rb +3 -0
- data/lib/phraseapp-in-context-editor-ruby/view_helpers.rb +2 -1
- data/lib/phraseapp-in-context-editor-ruby.rb +8 -0
- data/package-lock.json +6576 -0
- data/package.json +13 -0
- data/phraseapp-in-context-editor-ruby.gemspec +4 -2
- data/release.config.js +10 -0
- metadata +97 -7
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
.rails-default-error-page {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
.rails-default-error-page div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
.rails-default-error-page div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
.rails-default-error-page h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
.rails-default-error-page div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body class="rails-default-error-page">
|
58
|
+
<!-- This file lives in public/500.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>We're sorry, but something went wrong.</h1>
|
62
|
+
</div>
|
63
|
+
<p>If you are the application owner check the logs for more information.</p>
|
64
|
+
</div>
|
65
|
+
</body>
|
66
|
+
</html>
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,13 @@
|
|
1
|
+
ENV["RAILS_ENV"] ||= "test"
|
2
|
+
require_relative "../config/environment"
|
3
|
+
require "rails/test_help"
|
4
|
+
|
5
|
+
class ActiveSupport::TestCase
|
6
|
+
# Run tests in parallel with specified workers
|
7
|
+
parallelize(workers: :number_of_processors)
|
8
|
+
|
9
|
+
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
|
10
|
+
fixtures :all
|
11
|
+
|
12
|
+
# Add more helper methods to be used by all tests here...
|
13
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -9,6 +9,10 @@ PhraseApp::InContextEditor.configure do |config|
|
|
9
9
|
config.account_id = "<%= options[:account_id] %>"
|
10
10
|
config.datacenter = "eu"
|
11
11
|
|
12
|
+
# Configure an array of key names that should not be handled
|
13
|
+
# by the In-Context-Editor.
|
14
|
+
# config.ignored_keys = ["number.*", "foo.bar"]
|
15
|
+
|
12
16
|
# Phrase uses decorators to generate a unique identification key
|
13
17
|
# in context of your document. However, this might result in conflicts
|
14
18
|
# with other libraries (e.g. client-side template engines) that use a similar syntax.
|
@@ -1,8 +1,8 @@
|
|
1
1
|
if defined?(I18n)
|
2
2
|
module I18n
|
3
3
|
class << self
|
4
|
-
def translate_with_phraseapp(
|
5
|
-
PhraseApp::InContextEditor.backend.translate(
|
4
|
+
def translate_with_phraseapp(...)
|
5
|
+
PhraseApp::InContextEditor.backend.translate(...)
|
6
6
|
end
|
7
7
|
alias_method :translate_without_phraseapp, :translate
|
8
8
|
alias_method :translate, :translate_with_phraseapp
|
@@ -3,47 +3,32 @@ require_relative "delegate/i18n_delegate"
|
|
3
3
|
module PhraseApp
|
4
4
|
module InContextEditor
|
5
5
|
class BackendService
|
6
|
-
attr_accessor :blacklisted_keys
|
7
|
-
|
8
6
|
def initialize(args = {})
|
9
7
|
self
|
10
8
|
end
|
11
9
|
|
12
|
-
def translate(
|
13
|
-
if to_be_translated_without_phraseapp?(
|
14
|
-
|
15
|
-
#
|
16
|
-
# This method uses keyword arguments.
|
17
|
-
# There is a breaking change in ruby that produces warning with ruby 2.7 and won't work as expected with ruby 3.0
|
18
|
-
# The "hash" parameter must be passed as keyword argument.
|
19
|
-
#
|
20
|
-
# Good:
|
21
|
-
# I18n.t(:salutation, :gender => 'w', :name => 'Smith')
|
22
|
-
# I18n.t(:salutation, **{ :gender => 'w', :name => 'Smith' })
|
23
|
-
# I18n.t(:salutation, **any_hash)
|
24
|
-
#
|
25
|
-
# Bad:
|
26
|
-
# I18n.t(:salutation, { :gender => 'w', :name => 'Smith' })
|
27
|
-
# I18n.t(:salutation, any_hash)
|
28
|
-
#
|
29
|
-
kw_args = args[1]
|
30
|
-
if kw_args.present?
|
31
|
-
I18n.translate_without_phraseapp(args[0], **kw_args)
|
32
|
-
else
|
33
|
-
I18n.translate_without_phraseapp(args[0])
|
34
|
-
end
|
10
|
+
def translate(...)
|
11
|
+
if to_be_translated_without_phraseapp?(...)
|
12
|
+
I18n.translate_without_phraseapp(...)
|
35
13
|
else
|
36
|
-
phraseapp_delegate_for(
|
14
|
+
phraseapp_delegate_for(...)
|
37
15
|
end
|
38
16
|
end
|
39
17
|
|
40
18
|
protected
|
41
19
|
|
42
|
-
def to_be_translated_without_phraseapp?(
|
43
|
-
PhraseApp::InContextEditor.disabled? || has_been_forced_to_resolve_with_phraseapp?(
|
20
|
+
def to_be_translated_without_phraseapp?(...)
|
21
|
+
PhraseApp::InContextEditor.disabled? || ignored_key?(...) || has_been_forced_to_resolve_with_phraseapp?(...)
|
22
|
+
end
|
23
|
+
|
24
|
+
def ignored_key?(*args)
|
25
|
+
key = given_key_from_args(args)
|
26
|
+
PhraseApp::InContextEditor.ignored_keys.any? do |ignored_key|
|
27
|
+
key.to_s[/\A#{ignored_key.gsub("*", ".*")}\Z/]
|
28
|
+
end
|
44
29
|
end
|
45
30
|
|
46
|
-
def has_been_forced_to_resolve_with_phraseapp?(args)
|
31
|
+
def has_been_forced_to_resolve_with_phraseapp?(*args)
|
47
32
|
(args.last.is_a?(Hash) && args.last[:resolve] == false)
|
48
33
|
end
|
49
34
|
|
@@ -51,11 +36,11 @@ module PhraseApp
|
|
51
36
|
extract_normalized_key_from_args(args)
|
52
37
|
end
|
53
38
|
|
54
|
-
def phraseapp_delegate_for(args)
|
39
|
+
def phraseapp_delegate_for(*args)
|
55
40
|
key = given_key_from_args(args)
|
56
41
|
return nil unless present?(key)
|
57
42
|
|
58
|
-
options = args
|
43
|
+
options = options_from_args(args)
|
59
44
|
PhraseApp::InContextEditor::Delegate::I18nDelegate.new(key, options, args)
|
60
45
|
end
|
61
46
|
|
@@ -8,7 +8,9 @@ module PhraseApp
|
|
8
8
|
enabled: false,
|
9
9
|
backend: PhraseApp::InContextEditor::BackendService.new,
|
10
10
|
prefix: "{{__",
|
11
|
-
suffix: "__}}"
|
11
|
+
suffix: "__}}",
|
12
|
+
origin: "in-context-editor-ruby",
|
13
|
+
ignored_keys: []
|
12
14
|
}.freeze
|
13
15
|
|
14
16
|
CONFIG_OPTIONS.each do |option, default_value|
|
@@ -4,7 +4,7 @@ module PhraseApp
|
|
4
4
|
module InContextEditor
|
5
5
|
module Delegate
|
6
6
|
class I18nDelegate < Base
|
7
|
-
attr_accessor :key, :display_key
|
7
|
+
attr_accessor :key, :display_key
|
8
8
|
|
9
9
|
def initialize(key, options = {}, original_args = nil)
|
10
10
|
@key = key
|
@@ -24,7 +24,7 @@ module PhraseApp
|
|
24
24
|
data.send(*args, &block)
|
25
25
|
else
|
26
26
|
self.class.log "You tried to execute the missing method ##{args.first} on key #{@key} which is not supported. Please make sure you treat your translations as strings only."
|
27
|
-
original_translation = ::I18n.translate_without_phraseapp(*@original_args)
|
27
|
+
original_translation = ::I18n.translate_without_phraseapp(*@original_args, **@options)
|
28
28
|
original_translation.send(*args, &block)
|
29
29
|
end
|
30
30
|
end
|
@@ -17,7 +17,8 @@ module PhraseApp
|
|
17
17
|
"accountId" => PhraseApp::InContextEditor.account_id,
|
18
18
|
"datacenter" => PhraseApp::InContextEditor.datacenter,
|
19
19
|
"prefix" => PhraseApp::InContextEditor.prefix,
|
20
|
-
"suffix" => PhraseApp::InContextEditor.suffix
|
20
|
+
"suffix" => PhraseApp::InContextEditor.suffix,
|
21
|
+
"origin" => PhraseApp::InContextEditor.origin
|
21
22
|
}.merge(opts)
|
22
23
|
|
23
24
|
snippet = <<-EOS
|
@@ -37,6 +37,10 @@ module PhraseApp
|
|
37
37
|
config.datacenter
|
38
38
|
end
|
39
39
|
|
40
|
+
def ignored_keys
|
41
|
+
config.ignored_keys
|
42
|
+
end
|
43
|
+
|
40
44
|
def enabled=(value)
|
41
45
|
config.enabled = value
|
42
46
|
end
|
@@ -48,6 +52,10 @@ module PhraseApp
|
|
48
52
|
def disabled?
|
49
53
|
!config.enabled
|
50
54
|
end
|
55
|
+
|
56
|
+
def origin
|
57
|
+
config.origin
|
58
|
+
end
|
51
59
|
end
|
52
60
|
|
53
61
|
def self.configure
|