phraseapp-in-context-editor-ruby 1.4.0 → 2.1.1
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 +8 -9
- data/.gitignore +1 -1
- data/.tool-versions +1 -1
- data/CHANGELOG.md +9 -105
- data/CODEOWNERS +1 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +244 -0
- data/Guardfile +13 -13
- data/README.md +81 -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 +9 -17
- 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 +12 -99
- data/lib/phraseapp-in-context-editor-ruby/config.rb +13 -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 +4 -50
- 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 +1 -3
- data/lib/phraseapp-in-context-editor-ruby/view_helpers.rb +26 -19
- data/lib/phraseapp-in-context-editor-ruby.rb +17 -52
- 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,18 @@ 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] %>"
|
9
|
+
config.account_id = "<%= options[:account_id] %>"
|
10
|
+
config.datacenter = "eu"
|
10
11
|
|
11
|
-
#
|
12
|
-
# in Translation Center or via the Authorizations API
|
13
|
-
# (https://developers.phraseapp.com/api/#authorizations).
|
14
|
-
config.access_token = "<%= options[:access_token] %>"
|
15
|
-
|
16
|
-
# Configure an array of key names that should not be handled
|
17
|
-
# by the In-Context-Editor.
|
18
|
-
config.ignored_keys = ["number.*", "breadcrumb.*"]
|
19
|
-
|
20
|
-
# PhraseApp uses decorators to generate a unique identification key
|
12
|
+
# Phrase uses decorators to generate a unique identification key
|
21
13
|
# in context of your document. However, this might result in conflicts
|
22
14
|
# with other libraries (e.g. client-side template engines) that use a similar syntax.
|
23
15
|
# If you encounter this problem, you might want to change this decorator pattern.
|
24
|
-
# More information: https://help.
|
25
|
-
# config.prefix = "
|
26
|
-
# config.suffix = "__
|
16
|
+
# More information: https://help.phrase.com/hc/en-us/articles/5784095916188-In-Context-Editor-Strings-
|
17
|
+
# config.prefix = "[[__"
|
18
|
+
# config.suffix = "__]]"
|
27
19
|
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(*args)
|
5
|
+
PhraseApp::InContextEditor.backend.translate(*args)
|
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,11 +1,8 @@
|
|
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
6
|
attr_accessor :blacklisted_keys
|
10
7
|
|
11
8
|
def initialize(args = {})
|
@@ -40,47 +37,20 @@ module PhraseApp
|
|
40
37
|
end
|
41
38
|
end
|
42
39
|
|
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
|
47
|
-
|
48
|
-
def has_been_given_blacklisted_key?(args)
|
49
|
-
key = given_key_from_args(args)
|
50
|
-
has_blacklist_entry_for_key?(key)
|
51
|
-
end
|
40
|
+
protected
|
52
41
|
|
53
|
-
def
|
54
|
-
|
55
|
-
key_is_ignored?(key)
|
42
|
+
def to_be_translated_without_phraseapp?(args)
|
43
|
+
PhraseApp::InContextEditor.disabled? || has_been_forced_to_resolve_with_phraseapp?(args)
|
56
44
|
end
|
57
45
|
|
58
46
|
def has_been_forced_to_resolve_with_phraseapp?(args)
|
59
|
-
(args.last.is_a?(Hash)
|
47
|
+
(args.last.is_a?(Hash) && args.last[:resolve] == false)
|
60
48
|
end
|
61
49
|
|
62
50
|
def given_key_from_args(args)
|
63
51
|
extract_normalized_key_from_args(args)
|
64
52
|
end
|
65
53
|
|
66
|
-
def has_blacklist_entry_for_key?(key)
|
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
54
|
def phraseapp_delegate_for(args)
|
85
55
|
key = given_key_from_args(args)
|
86
56
|
return nil unless present?(key)
|
@@ -95,15 +65,14 @@ module PhraseApp
|
|
95
65
|
end
|
96
66
|
|
97
67
|
def transform_args(args)
|
98
|
-
duped_args = args.map { |item| (item.is_a?(Symbol)
|
99
|
-
transform_args_based_on_caller(duped_args)
|
68
|
+
duped_args = args.map { |item| (item.is_a?(Symbol) || item.nil?) ? item : item.dup }
|
100
69
|
end
|
101
70
|
|
102
71
|
def normalized_key(duped_args)
|
103
72
|
splitted_args = split_args(duped_args)
|
104
73
|
key = I18n::Backend::Flatten.normalize_flat_keys(*splitted_args)
|
105
74
|
key.gsub!("..", ".")
|
106
|
-
key.gsub!(/^\./,
|
75
|
+
key.gsub!(/^\./, "")
|
107
76
|
key
|
108
77
|
end
|
109
78
|
|
@@ -111,77 +80,21 @@ module PhraseApp
|
|
111
80
|
options = options_from_args(args)
|
112
81
|
key ||= args.shift
|
113
82
|
locale = options.delete(:locale) || I18n.locale
|
114
|
-
|
83
|
+
[locale, key, options[:scope], nil]
|
115
84
|
end
|
116
85
|
|
117
86
|
def options_from_args(args)
|
118
87
|
args.last.is_a?(Hash) ? args.pop : {}
|
119
88
|
end
|
120
89
|
|
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
90
|
def blank?(str)
|
157
|
-
raise "blank?(str) can only be given a String or nil" unless str.is_a?(String)
|
158
|
-
str.nil?
|
91
|
+
raise "blank?(str) can only be given a String or nil" unless str.is_a?(String) || str.nil?
|
92
|
+
str.nil? || str == ""
|
159
93
|
end
|
160
94
|
|
161
95
|
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
|
96
|
+
raise "present?(str) can only be given a String or nil" unless str.is_a?(String) || str.nil?
|
97
|
+
!blank?(str)
|
185
98
|
end
|
186
99
|
end
|
187
100
|
end
|
@@ -1,62 +1,40 @@
|
|
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
|
-
js_host: "phraseapp.com",
|
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"
|
21
13
|
}.freeze
|
22
14
|
|
23
|
-
CONFIG_OPTIONS_GLOBAL_ONLY = [
|
24
|
-
:access_token,
|
25
|
-
:skip_ssl_verification,
|
26
|
-
:api_host
|
27
|
-
].freeze
|
28
|
-
|
29
15
|
CONFIG_OPTIONS.each do |option, default_value|
|
30
|
-
class_eval "@@#{option} = CONFIG_OPTIONS[:#{option}]"
|
16
|
+
class_eval "@@#{option} = CONFIG_OPTIONS[:#{option}]", __FILE__, __LINE__
|
31
17
|
|
32
18
|
define_method("#{option}=") do |value|
|
33
|
-
instance_eval "@#{option} = value
|
34
|
-
end
|
19
|
+
instance_eval "@#{option} = value", __FILE__, __LINE__
|
20
|
+
end
|
35
21
|
|
36
|
-
define_method(
|
37
|
-
instance_eval "defined?(@#{option}) ? @#{option} : self.class.#{option}"
|
22
|
+
define_method(option.to_s) do
|
23
|
+
instance_eval "defined?(@#{option}) ? @#{option} : self.class.#{option}", __FILE__, __LINE__
|
38
24
|
end
|
39
25
|
|
40
26
|
define_singleton_method("#{option}=") do |value|
|
41
|
-
instance_eval "@@#{option} = value
|
27
|
+
instance_eval "@@#{option} = value", __FILE__, __LINE__
|
42
28
|
end
|
43
29
|
|
44
|
-
define_singleton_method(
|
45
|
-
instance_eval "@@#{option}"
|
30
|
+
define_singleton_method(option.to_s) do
|
31
|
+
instance_eval "@@#{option}", __FILE__, __LINE__
|
46
32
|
end
|
47
33
|
end
|
48
34
|
|
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={})
|
35
|
+
def assign_values(config_options = {})
|
58
36
|
config_options.each do |config_option, value|
|
59
|
-
|
37
|
+
send("#{config_option}=", value)
|
60
38
|
end
|
61
39
|
end
|
62
40
|
|
@@ -65,20 +43,6 @@ module PhraseApp
|
|
65
43
|
send("#{option}=", default_value)
|
66
44
|
end
|
67
45
|
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
46
|
end
|
83
47
|
end
|
84
48
|
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
|
@@ -1,12 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'phraseapp-in-context-editor-ruby/cache'
|
4
|
-
require 'phraseapp-in-context-editor-ruby/hash_flattener'
|
5
|
-
require 'phraseapp-in-context-editor-ruby/delegate'
|
6
|
-
require 'phraseapp-in-context-editor-ruby/api_wrapper'
|
7
|
-
require 'phraseapp-in-context-editor-ruby/displayable_key_identifier'
|
8
|
-
|
9
|
-
require 'set'
|
1
|
+
require_relative "../delegate"
|
10
2
|
|
11
3
|
module PhraseApp
|
12
4
|
module InContextEditor
|
@@ -14,11 +6,11 @@ module PhraseApp
|
|
14
6
|
class I18nDelegate < Base
|
15
7
|
attr_accessor :key, :display_key, :options, :api_client, :fallback_keys, :original_args
|
16
8
|
|
17
|
-
def initialize(key, options={}, original_args=nil)
|
9
|
+
def initialize(key, options = {}, original_args = nil)
|
18
10
|
@key = key
|
19
11
|
@options = options
|
20
12
|
@original_args = original_args
|
21
|
-
@display_key =
|
13
|
+
@display_key = @key
|
22
14
|
super(decorated_key_name)
|
23
15
|
end
|
24
16
|
|
@@ -27,7 +19,7 @@ module PhraseApp
|
|
27
19
|
if @key.respond_to?(args.first)
|
28
20
|
to_s.send(*args)
|
29
21
|
else
|
30
|
-
data =
|
22
|
+
data = [@key]
|
31
23
|
if data.respond_to?(args.first)
|
32
24
|
data.send(*args, &block)
|
33
25
|
else
|
@@ -37,44 +29,6 @@ module PhraseApp
|
|
37
29
|
end
|
38
30
|
end
|
39
31
|
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def translation_or_subkeys
|
44
|
-
return nil if @key.nil? || @key.to_s == ""
|
45
|
-
|
46
|
-
keys = api_wrapper.keys_with_prefix(@key)
|
47
|
-
return nil unless keys.present?
|
48
|
-
|
49
|
-
if keys.size == 1
|
50
|
-
translation_content_for_key(keys.first)
|
51
|
-
else
|
52
|
-
translation_hash = keys.inject({}) do |hash, key|
|
53
|
-
hash[key.name] = translation_content_for_key(key)
|
54
|
-
hash
|
55
|
-
end
|
56
|
-
|
57
|
-
PhraseApp::InContextEditor::HashFlattener.expand_flat_hash(translation_hash, @key)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def translation_content_for_key(key)
|
62
|
-
default_translations = api_wrapper.default_translation(key)
|
63
|
-
return unless default_translations.present?
|
64
|
-
|
65
|
-
if key.plural
|
66
|
-
default_translations.inject({}) do |hash, translation|
|
67
|
-
hash[translation.plural_suffix.to_sym] = translation.content
|
68
|
-
hash
|
69
|
-
end
|
70
|
-
else
|
71
|
-
default_translations.first.content
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def api_wrapper
|
76
|
-
@api_wrapper ||= InContextEditor::ApiWrapper.new
|
77
|
-
end
|
78
32
|
end
|
79
33
|
end
|
80
34
|
end
|