phraseapp-in-context-editor-ruby 1.4.0 → 3.2.0
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 +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 +36 -0
- data/.github/workflows/test.yml +8 -9
- data/.gitignore +1 -1
- data/.tool-versions +1 -1
- data/CHANGELOG.md +28 -79
- data/CODEOWNERS +1 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +244 -0
- data/Guardfile +13 -13
- data/README.md +96 -51
- data/RELEASING.md +3 -0
- 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/install_generator.rb +3 -9
- data/lib/generators/phraseapp_in_context_editor/templates/phraseapp_in_context_editor.rb +10 -14
- data/lib/phraseapp-in-context-editor-ruby/adapters/fast_gettext.rb +20 -20
- data/lib/phraseapp-in-context-editor-ruby/adapters/i18n.rb +10 -10
- data/lib/phraseapp-in-context-editor-ruby/backend_service.rb +23 -125
- data/lib/phraseapp-in-context-editor-ruby/config.rb +14 -49
- data/lib/phraseapp-in-context-editor-ruby/delegate/fast_gettext.rb +13 -15
- data/lib/phraseapp-in-context-editor-ruby/delegate/i18n_delegate.rb +6 -52
- data/lib/phraseapp-in-context-editor-ruby/delegate.rb +13 -14
- data/lib/phraseapp-in-context-editor-ruby/engine.rb +5 -6
- data/lib/phraseapp-in-context-editor-ruby/version.rb +2 -4
- data/lib/phraseapp-in-context-editor-ruby/view_helpers.rb +26 -19
- data/lib/phraseapp-in-context-editor-ruby.rb +17 -48
- data/package-lock.json +6576 -0
- data/package.json +13 -0
- data/phraseapp-in-context-editor-ruby.gemspec +19 -32
- data/release.config.js +10 -0
- metadata +113 -97
- data/lib/generators/phraseapp_in_context_editor/templates/README +0 -10
- data/lib/phraseapp-in-context-editor-ruby/api_collection.rb +0 -41
- data/lib/phraseapp-in-context-editor-ruby/api_wrapper.rb +0 -59
- data/lib/phraseapp-in-context-editor-ruby/cache.rb +0 -37
- data/lib/phraseapp-in-context-editor-ruby/displayable_key_identifier.rb +0 -46
- data/lib/phraseapp-in-context-editor-ruby/fallback_keys_fetcher.rb +0 -44
- data/lib/phraseapp-in-context-editor-ruby/hash_flattener.rb +0 -53
- data/lib/phraseapp-in-context-editor-ruby/key_names_cache.rb +0 -53
@@ -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
|
@@ -1,21 +1,15 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
|
-
|
3
1
|
module PhraseappInContextEditor
|
4
2
|
module Generators
|
5
3
|
class InstallGenerator < Rails::Generators::Base
|
6
4
|
source_root File.expand_path("../templates", __FILE__)
|
7
5
|
|
8
|
-
desc "Creates a
|
9
|
-
class_option :
|
10
|
-
class_option :project_id, type: :string, desc: "Your
|
6
|
+
desc "Creates a Phrase In-Context-Editor initializer for your application."
|
7
|
+
class_option :account_id, type: :string, desc: "Your Phrase account id", required: true
|
8
|
+
class_option :project_id, type: :string, desc: "Your Phrase project id", required: true
|
11
9
|
|
12
10
|
def copy_initializer
|
13
11
|
template "phraseapp_in_context_editor.rb", "config/initializers/phraseapp_in_context_editor.rb"
|
14
12
|
end
|
15
|
-
|
16
|
-
def show_readme
|
17
|
-
readme "README" if behavior == :invoke
|
18
|
-
end
|
19
13
|
end
|
20
14
|
end
|
21
15
|
end
|
@@ -2,26 +2,22 @@ PhraseApp::InContextEditor.configure do |config|
|
|
2
2
|
# Enable or disable the In-Context-Editor in general
|
3
3
|
config.enabled = true
|
4
4
|
|
5
|
-
#
|
6
|
-
# in
|
7
|
-
#
|
8
|
-
# page (https://phraseapp.com/projects)
|
5
|
+
# Configure with your project id and account id. You can find the
|
6
|
+
# project id in your project settings and account id in your account
|
7
|
+
# settings (https://app.phrase.com/)
|
9
8
|
config.project_id = "<%= options[:project_id] %>"
|
10
|
-
|
11
|
-
|
12
|
-
# in Translation Center or via the Authorizations API
|
13
|
-
# (https://developers.phraseapp.com/api/#authorizations).
|
14
|
-
config.access_token = "<%= options[:access_token] %>"
|
9
|
+
config.account_id = "<%= options[:account_id] %>"
|
10
|
+
config.datacenter = "eu"
|
15
11
|
|
16
12
|
# Configure an array of key names that should not be handled
|
17
13
|
# by the In-Context-Editor.
|
18
|
-
config.ignored_keys = ["number.*", "
|
14
|
+
# config.ignored_keys = ["number.*", "foo.bar"]
|
19
15
|
|
20
|
-
#
|
16
|
+
# Phrase uses decorators to generate a unique identification key
|
21
17
|
# in context of your document. However, this might result in conflicts
|
22
18
|
# with other libraries (e.g. client-side template engines) that use a similar syntax.
|
23
19
|
# If you encounter this problem, you might want to change this decorator pattern.
|
24
|
-
# More information: https://help.
|
25
|
-
# config.prefix = "
|
26
|
-
# config.suffix = "__
|
20
|
+
# More information: https://help.phrase.com/hc/en-us/articles/5784095916188-In-Context-Editor-Strings-
|
21
|
+
# config.prefix = "[[__"
|
22
|
+
# config.suffix = "__]]"
|
27
23
|
end
|
@@ -1,25 +1,25 @@
|
|
1
|
-
|
1
|
+
require "phraseapp-in-context-editor-ruby/delegate/fast_gettext"
|
2
2
|
|
3
|
-
|
3
|
+
if defined? FastGettext::Translation
|
4
|
+
module FastGettext
|
5
|
+
module Translation
|
6
|
+
def __with_phraseapp(*args)
|
7
|
+
PhraseApp::InContextEditor::Delegate::FastGettext.new(:_, *args)
|
8
|
+
end
|
9
|
+
alias_method :__without_phraseapp, :_
|
10
|
+
alias_method :_, :__with_phraseapp
|
4
11
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
alias_method :__without_phraseapp, :_
|
11
|
-
alias_method :_, :__with_phraseapp
|
12
|
-
|
13
|
-
def n__with_phraseapp(*args)
|
14
|
-
PhraseApp::InContextEditor::Delegate::FastGettext.new(:n_, *args)
|
15
|
-
end
|
16
|
-
alias_method :n__without_phraseapp, :n_
|
17
|
-
alias_method :n_, :n__with_phraseapp
|
12
|
+
def n__with_phraseapp(*args)
|
13
|
+
PhraseApp::InContextEditor::Delegate::FastGettext.new(:n_, *args)
|
14
|
+
end
|
15
|
+
alias_method :n__without_phraseapp, :n_
|
16
|
+
alias_method :n_, :n__with_phraseapp
|
18
17
|
|
19
|
-
|
20
|
-
|
18
|
+
def s__with_phraseapp(*args)
|
19
|
+
PhraseApp::InContextEditor::Delegate::FastGettext.new(:s_, *args)
|
20
|
+
end
|
21
|
+
alias_method :s__without_phraseapp, :s_
|
22
|
+
alias_method :s_, :s__with_phraseapp
|
21
23
|
end
|
22
|
-
alias_method :s__without_phraseapp, :s_
|
23
|
-
alias_method :s_, :s__with_phraseapp
|
24
24
|
end
|
25
|
-
end
|
25
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
if defined?(I18n)
|
2
|
+
module I18n
|
3
|
+
class << self
|
4
|
+
def translate_with_phraseapp(...)
|
5
|
+
PhraseApp::InContextEditor.backend.translate(...)
|
6
|
+
end
|
7
|
+
alias_method :translate_without_phraseapp, :translate
|
8
|
+
alias_method :translate, :translate_with_phraseapp
|
9
|
+
alias_method :t, :translate
|
7
10
|
end
|
8
|
-
alias_method :translate_without_phraseapp, :translate
|
9
|
-
alias_method :translate, :translate_with_phraseapp
|
10
|
-
alias_method :t, :translate
|
11
11
|
end
|
12
|
-
end
|
12
|
+
end
|
@@ -1,91 +1,46 @@
|
|
1
|
-
|
2
|
-
require 'phraseapp-in-context-editor-ruby/api_collection'
|
3
|
-
require 'phraseapp-in-context-editor-ruby/delegate/i18n_delegate'
|
1
|
+
require_relative "delegate/i18n_delegate"
|
4
2
|
|
5
3
|
module PhraseApp
|
6
4
|
module InContextEditor
|
7
5
|
class BackendService
|
8
|
-
|
9
|
-
attr_accessor :blacklisted_keys
|
10
|
-
|
11
6
|
def initialize(args = {})
|
12
7
|
self
|
13
8
|
end
|
14
9
|
|
15
|
-
def translate(
|
16
|
-
if to_be_translated_without_phraseapp?(
|
17
|
-
|
18
|
-
#
|
19
|
-
# This method uses keyword arguments.
|
20
|
-
# There is a breaking change in ruby that produces warning with ruby 2.7 and won't work as expected with ruby 3.0
|
21
|
-
# The "hash" parameter must be passed as keyword argument.
|
22
|
-
#
|
23
|
-
# Good:
|
24
|
-
# I18n.t(:salutation, :gender => 'w', :name => 'Smith')
|
25
|
-
# I18n.t(:salutation, **{ :gender => 'w', :name => 'Smith' })
|
26
|
-
# I18n.t(:salutation, **any_hash)
|
27
|
-
#
|
28
|
-
# Bad:
|
29
|
-
# I18n.t(:salutation, { :gender => 'w', :name => 'Smith' })
|
30
|
-
# I18n.t(:salutation, any_hash)
|
31
|
-
#
|
32
|
-
kw_args = args[1]
|
33
|
-
if kw_args.present?
|
34
|
-
I18n.translate_without_phraseapp(args[0], **kw_args)
|
35
|
-
else
|
36
|
-
I18n.translate_without_phraseapp(args[0])
|
37
|
-
end
|
10
|
+
def translate(...)
|
11
|
+
if to_be_translated_without_phraseapp?(...)
|
12
|
+
I18n.translate_without_phraseapp(...)
|
38
13
|
else
|
39
|
-
phraseapp_delegate_for(
|
14
|
+
phraseapp_delegate_for(...)
|
40
15
|
end
|
41
16
|
end
|
42
17
|
|
43
|
-
|
44
|
-
def to_be_translated_without_phraseapp?(args)
|
45
|
-
PhraseApp::InContextEditor.disabled? or has_been_given_blacklisted_key?(args) or has_been_given_ignored_key?(args) or has_been_forced_to_resolve_with_phraseapp?(args)
|
46
|
-
end
|
18
|
+
protected
|
47
19
|
|
48
|
-
def
|
49
|
-
|
50
|
-
has_blacklist_entry_for_key?(key)
|
20
|
+
def to_be_translated_without_phraseapp?(...)
|
21
|
+
PhraseApp::InContextEditor.disabled? || ignored_key?(...) || has_been_forced_to_resolve_with_phraseapp?(...)
|
51
22
|
end
|
52
23
|
|
53
|
-
def
|
24
|
+
def ignored_key?(*args)
|
54
25
|
key = given_key_from_args(args)
|
55
|
-
|
26
|
+
PhraseApp::InContextEditor.ignored_keys.any? do |ignored_key|
|
27
|
+
key.to_s[/\A#{ignored_key.gsub("*", ".*")}\Z/]
|
28
|
+
end
|
56
29
|
end
|
57
30
|
|
58
|
-
def has_been_forced_to_resolve_with_phraseapp?(args)
|
59
|
-
(args.last.is_a?(Hash)
|
31
|
+
def has_been_forced_to_resolve_with_phraseapp?(*args)
|
32
|
+
(args.last.is_a?(Hash) && args.last[:resolve] == false)
|
60
33
|
end
|
61
34
|
|
62
35
|
def given_key_from_args(args)
|
63
36
|
extract_normalized_key_from_args(args)
|
64
37
|
end
|
65
38
|
|
66
|
-
def
|
67
|
-
blacklisted_keys.each do |blacklisted_key|
|
68
|
-
return true if present?(key.to_s[/\A#{blacklisted_key.gsub("*", ".*")}\Z/])
|
69
|
-
end
|
70
|
-
false
|
71
|
-
end
|
72
|
-
|
73
|
-
def key_is_ignored?(key)
|
74
|
-
PhraseApp::InContextEditor.ignored_keys.each do |ignored_key|
|
75
|
-
return true if present?(key.to_s[/\A#{ignored_key.gsub("*", ".*")}\Z/])
|
76
|
-
end
|
77
|
-
false
|
78
|
-
end
|
79
|
-
|
80
|
-
def blacklisted_keys
|
81
|
-
@blacklisted_keys ||= api_wrapper.blacklisted_keys
|
82
|
-
end
|
83
|
-
|
84
|
-
def phraseapp_delegate_for(args)
|
39
|
+
def phraseapp_delegate_for(*args)
|
85
40
|
key = given_key_from_args(args)
|
86
41
|
return nil unless present?(key)
|
87
42
|
|
88
|
-
options = args
|
43
|
+
options = options_from_args(args)
|
89
44
|
PhraseApp::InContextEditor::Delegate::I18nDelegate.new(key, options, args)
|
90
45
|
end
|
91
46
|
|
@@ -95,15 +50,14 @@ module PhraseApp
|
|
95
50
|
end
|
96
51
|
|
97
52
|
def transform_args(args)
|
98
|
-
duped_args = args.map { |item| (item.is_a?(Symbol)
|
99
|
-
transform_args_based_on_caller(duped_args)
|
53
|
+
duped_args = args.map { |item| (item.is_a?(Symbol) || item.nil?) ? item : item.dup }
|
100
54
|
end
|
101
55
|
|
102
56
|
def normalized_key(duped_args)
|
103
57
|
splitted_args = split_args(duped_args)
|
104
58
|
key = I18n::Backend::Flatten.normalize_flat_keys(*splitted_args)
|
105
59
|
key.gsub!("..", ".")
|
106
|
-
key.gsub!(/^\./,
|
60
|
+
key.gsub!(/^\./, "")
|
107
61
|
key
|
108
62
|
end
|
109
63
|
|
@@ -111,77 +65,21 @@ module PhraseApp
|
|
111
65
|
options = options_from_args(args)
|
112
66
|
key ||= args.shift
|
113
67
|
locale = options.delete(:locale) || I18n.locale
|
114
|
-
|
68
|
+
[locale, key, options[:scope], nil]
|
115
69
|
end
|
116
70
|
|
117
71
|
def options_from_args(args)
|
118
72
|
args.last.is_a?(Hash) ? args.pop : {}
|
119
73
|
end
|
120
74
|
|
121
|
-
def transform_args_based_on_caller(args)
|
122
|
-
translation_caller = identify_caller
|
123
|
-
|
124
|
-
if translation_caller and args.first =~ /^\./
|
125
|
-
options = options_from_args(args)
|
126
|
-
|
127
|
-
if not present?(options[:scope]) and present?(translation_caller)
|
128
|
-
options[:scope] = translation_caller
|
129
|
-
end
|
130
|
-
|
131
|
-
args.push(options)
|
132
|
-
parts = args.first.to_s.split(".").select { |e| not blank?(e) }
|
133
|
-
args[0] = parts[0] if parts.size == 1
|
134
|
-
end
|
135
|
-
|
136
|
-
args
|
137
|
-
end
|
138
|
-
|
139
|
-
def identify_caller
|
140
|
-
translation_caller = nil
|
141
|
-
send(:caller)[0..6].each do |intermediate_caller|
|
142
|
-
translation_caller = calling_template(intermediate_caller) unless translation_caller
|
143
|
-
end
|
144
|
-
|
145
|
-
if present?(translation_caller)
|
146
|
-
find_lookup_scope(translation_caller)
|
147
|
-
else
|
148
|
-
nil
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def calling_template(string)
|
153
|
-
string.match(/(views)(\/.+)(?>:[0-9]+:in)/)
|
154
|
-
end
|
155
|
-
|
156
75
|
def blank?(str)
|
157
|
-
raise "blank?(str) can only be given a String or nil" unless str.is_a?(String)
|
158
|
-
str.nil?
|
76
|
+
raise "blank?(str) can only be given a String or nil" unless str.is_a?(String) || str.nil?
|
77
|
+
str.nil? || str == ""
|
159
78
|
end
|
160
79
|
|
161
80
|
def present?(str)
|
162
|
-
raise "present?(str) can only be given a String or nil" unless str.is_a?(String)
|
163
|
-
|
164
|
-
end
|
165
|
-
|
166
|
-
def find_lookup_scope(caller)
|
167
|
-
split_path = caller[2][1..-1].split(".")[0].split("/")
|
168
|
-
|
169
|
-
template_or_partial = remove_underscore_form_partial(split_path[-1])
|
170
|
-
split_path[-1] = template_or_partial
|
171
|
-
|
172
|
-
split_path.map!(&:to_sym)
|
173
|
-
end
|
174
|
-
|
175
|
-
def remove_underscore_form_partial(template_or_partial)
|
176
|
-
if template_or_partial.to_s[0,1] == "_"
|
177
|
-
template_or_partial.to_s[1..-1]
|
178
|
-
else
|
179
|
-
template_or_partial.to_s
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
def api_wrapper
|
184
|
-
@api_wrapper ||= PhraseApp::InContextEditor::ApiWrapper.new
|
81
|
+
raise "present?(str) can only be given a String or nil" unless str.is_a?(String) || str.nil?
|
82
|
+
!blank?(str)
|
185
83
|
end
|
186
84
|
end
|
187
85
|
end
|
@@ -1,62 +1,41 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module PhraseApp
|
3
2
|
module InContextEditor
|
4
3
|
class Config
|
5
4
|
CONFIG_OPTIONS = {
|
5
|
+
account_id: nil,
|
6
6
|
project_id: nil,
|
7
|
-
|
7
|
+
datacenter: "eu",
|
8
8
|
enabled: false,
|
9
|
-
skip_ssl_verification: false,
|
10
9
|
backend: PhraseApp::InContextEditor::BackendService.new,
|
11
10
|
prefix: "{{__",
|
12
11
|
suffix: "__}}",
|
13
|
-
|
14
|
-
|
15
|
-
js_use_ssl: true,
|
16
|
-
js_path: "/assets/in-context-editor/2.0/app.js",
|
17
|
-
js_options: {},
|
18
|
-
cache_key_segments_initial: ["simple_form"],
|
19
|
-
cache_lifetime: 300,
|
20
|
-
ignored_keys: [],
|
12
|
+
origin: "in-context-editor-ruby",
|
13
|
+
ignored_keys: []
|
21
14
|
}.freeze
|
22
15
|
|
23
|
-
CONFIG_OPTIONS_GLOBAL_ONLY = [
|
24
|
-
:access_token,
|
25
|
-
:skip_ssl_verification,
|
26
|
-
:api_host
|
27
|
-
].freeze
|
28
|
-
|
29
16
|
CONFIG_OPTIONS.each do |option, default_value|
|
30
|
-
class_eval "@@#{option} = CONFIG_OPTIONS[:#{option}]"
|
17
|
+
class_eval "@@#{option} = CONFIG_OPTIONS[:#{option}]", __FILE__, __LINE__
|
31
18
|
|
32
19
|
define_method("#{option}=") do |value|
|
33
|
-
instance_eval "@#{option} = value
|
34
|
-
end
|
20
|
+
instance_eval "@#{option} = value", __FILE__, __LINE__
|
21
|
+
end
|
35
22
|
|
36
|
-
define_method(
|
37
|
-
instance_eval "defined?(@#{option}) ? @#{option} : self.class.#{option}"
|
23
|
+
define_method(option.to_s) do
|
24
|
+
instance_eval "defined?(@#{option}) ? @#{option} : self.class.#{option}", __FILE__, __LINE__
|
38
25
|
end
|
39
26
|
|
40
27
|
define_singleton_method("#{option}=") do |value|
|
41
|
-
instance_eval "@@#{option} = value
|
28
|
+
instance_eval "@@#{option} = value", __FILE__, __LINE__
|
42
29
|
end
|
43
30
|
|
44
|
-
define_singleton_method(
|
45
|
-
instance_eval "@@#{option}"
|
31
|
+
define_singleton_method(option.to_s) do
|
32
|
+
instance_eval "@@#{option}", __FILE__, __LINE__
|
46
33
|
end
|
47
34
|
end
|
48
35
|
|
49
|
-
def
|
50
|
-
@@api_client ||= build_api_client
|
51
|
-
end
|
52
|
-
|
53
|
-
def api_client
|
54
|
-
self.class.api_client
|
55
|
-
end
|
56
|
-
|
57
|
-
def assign_values(config_options={})
|
36
|
+
def assign_values(config_options = {})
|
58
37
|
config_options.each do |config_option, value|
|
59
|
-
|
38
|
+
send("#{config_option}=", value)
|
60
39
|
end
|
61
40
|
end
|
62
41
|
|
@@ -65,20 +44,6 @@ module PhraseApp
|
|
65
44
|
send("#{option}=", default_value)
|
66
45
|
end
|
67
46
|
end
|
68
|
-
|
69
|
-
protected
|
70
|
-
def self.invalidate_api_client
|
71
|
-
@@api_client = nil
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.build_api_client
|
75
|
-
credentials = PhraseApp::Auth::Credentials.new(
|
76
|
-
token: @@access_token,
|
77
|
-
host: @@api_host,
|
78
|
-
skip_ssl_verification: @@skip_ssl_verification
|
79
|
-
)
|
80
|
-
PhraseApp::Client.new(credentials)
|
81
|
-
end
|
82
47
|
end
|
83
48
|
end
|
84
49
|
end
|
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'phraseapp-in-context-editor-ruby/delegate'
|
1
|
+
require_relative "../delegate"
|
4
2
|
|
5
3
|
module PhraseApp
|
6
4
|
module InContextEditor
|
@@ -12,20 +10,20 @@ module PhraseApp
|
|
12
10
|
@display_key = params[:msgid]
|
13
11
|
end
|
14
12
|
|
15
|
-
|
13
|
+
private
|
14
|
+
|
16
15
|
def params_from_args(args)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
16
|
+
case @method
|
17
|
+
when :_
|
18
|
+
{msgid: args.first}
|
19
|
+
when :n_
|
20
|
+
{msgid: args.first, msgid_plural: args[1], count: args.last}
|
21
|
+
when :s_
|
22
|
+
{msgid: args.first}
|
23
|
+
else
|
24
|
+
self.class.log("Unsupported FastGettext method #{@method}")
|
25
|
+
{}
|
27
26
|
end
|
28
|
-
params
|
29
27
|
end
|
30
28
|
end
|
31
29
|
end
|