phraseapp-in-context-editor-ruby 1.3.1 → 2.0.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/workflows/test.yml +12 -0
- data/.gitignore +0 -1
- data/.package-licenses.yml +4 -0
- data/.tool-versions +1 -0
- data/CHANGELOG.md +52 -6
- data/CODEOWNERS +1 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +241 -0
- data/Guardfile +13 -13
- data/README.md +81 -51
- data/RELEASING.md +10 -0
- data/config/license-decisions.yml +34 -0
- data/config/license_finder.yml +2 -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 +33 -100
- data/lib/phraseapp-in-context-editor-ruby/config.rb +13 -50
- 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/view_helpers.rb +25 -19
- data/lib/phraseapp-in-context-editor-ruby.rb +15 -54
- data/phraseapp-in-context-editor-ruby.gemspec +18 -33
- metadata +32 -103
- data/.travis.yml +0 -8
- 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
- data/lib/phraseapp-in-context-editor-ruby/version.rb +0 -5
@@ -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 = {})
|
@@ -14,53 +11,46 @@ module PhraseApp
|
|
14
11
|
|
15
12
|
def translate(*args)
|
16
13
|
if to_be_translated_without_phraseapp?(args)
|
17
|
-
|
14
|
+
# *Ruby 2.7+ keyword arguments warning*
|
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
|
18
35
|
else
|
19
36
|
phraseapp_delegate_for(args)
|
20
37
|
end
|
21
38
|
end
|
22
39
|
|
23
|
-
|
24
|
-
def to_be_translated_without_phraseapp?(args)
|
25
|
-
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)
|
26
|
-
end
|
40
|
+
protected
|
27
41
|
|
28
|
-
def
|
29
|
-
|
30
|
-
has_blacklist_entry_for_key?(key)
|
31
|
-
end
|
32
|
-
|
33
|
-
def has_been_given_ignored_key?(args)
|
34
|
-
key = given_key_from_args(args)
|
35
|
-
key_is_ignored?(key)
|
42
|
+
def to_be_translated_without_phraseapp?(args)
|
43
|
+
PhraseApp::InContextEditor.disabled? || has_been_forced_to_resolve_with_phraseapp?(args)
|
36
44
|
end
|
37
45
|
|
38
46
|
def has_been_forced_to_resolve_with_phraseapp?(args)
|
39
|
-
(args.last.is_a?(Hash)
|
47
|
+
(args.last.is_a?(Hash) && args.last[:resolve] == false)
|
40
48
|
end
|
41
49
|
|
42
50
|
def given_key_from_args(args)
|
43
51
|
extract_normalized_key_from_args(args)
|
44
52
|
end
|
45
53
|
|
46
|
-
def has_blacklist_entry_for_key?(key)
|
47
|
-
blacklisted_keys.each do |blacklisted_key|
|
48
|
-
return true if present?(key.to_s[/\A#{blacklisted_key.gsub("*", ".*")}\Z/])
|
49
|
-
end
|
50
|
-
false
|
51
|
-
end
|
52
|
-
|
53
|
-
def key_is_ignored?(key)
|
54
|
-
PhraseApp::InContextEditor.ignored_keys.each do |ignored_key|
|
55
|
-
return true if present?(key.to_s[/\A#{ignored_key.gsub("*", ".*")}\Z/])
|
56
|
-
end
|
57
|
-
false
|
58
|
-
end
|
59
|
-
|
60
|
-
def blacklisted_keys
|
61
|
-
@blacklisted_keys ||= api_wrapper.blacklisted_keys
|
62
|
-
end
|
63
|
-
|
64
54
|
def phraseapp_delegate_for(args)
|
65
55
|
key = given_key_from_args(args)
|
66
56
|
return nil unless present?(key)
|
@@ -75,15 +65,14 @@ module PhraseApp
|
|
75
65
|
end
|
76
66
|
|
77
67
|
def transform_args(args)
|
78
|
-
duped_args = args.map { |item| (item.is_a?(Symbol)
|
79
|
-
transform_args_based_on_caller(duped_args)
|
68
|
+
duped_args = args.map { |item| (item.is_a?(Symbol) || item.nil?) ? item : item.dup }
|
80
69
|
end
|
81
70
|
|
82
71
|
def normalized_key(duped_args)
|
83
72
|
splitted_args = split_args(duped_args)
|
84
73
|
key = I18n::Backend::Flatten.normalize_flat_keys(*splitted_args)
|
85
74
|
key.gsub!("..", ".")
|
86
|
-
key.gsub!(/^\./,
|
75
|
+
key.gsub!(/^\./, "")
|
87
76
|
key
|
88
77
|
end
|
89
78
|
|
@@ -91,77 +80,21 @@ module PhraseApp
|
|
91
80
|
options = options_from_args(args)
|
92
81
|
key ||= args.shift
|
93
82
|
locale = options.delete(:locale) || I18n.locale
|
94
|
-
|
83
|
+
[locale, key, options[:scope], nil]
|
95
84
|
end
|
96
85
|
|
97
86
|
def options_from_args(args)
|
98
87
|
args.last.is_a?(Hash) ? args.pop : {}
|
99
88
|
end
|
100
89
|
|
101
|
-
def transform_args_based_on_caller(args)
|
102
|
-
translation_caller = identify_caller
|
103
|
-
|
104
|
-
if translation_caller and args.first =~ /^\./
|
105
|
-
options = options_from_args(args)
|
106
|
-
|
107
|
-
if not present?(options[:scope]) and present?(translation_caller)
|
108
|
-
options[:scope] = translation_caller
|
109
|
-
end
|
110
|
-
|
111
|
-
args.push(options)
|
112
|
-
parts = args.first.to_s.split(".").select { |e| not blank?(e) }
|
113
|
-
args[0] = parts[0] if parts.size == 1
|
114
|
-
end
|
115
|
-
|
116
|
-
args
|
117
|
-
end
|
118
|
-
|
119
|
-
def identify_caller
|
120
|
-
translation_caller = nil
|
121
|
-
send(:caller)[0..6].each do |intermediate_caller|
|
122
|
-
translation_caller = calling_template(intermediate_caller) unless translation_caller
|
123
|
-
end
|
124
|
-
|
125
|
-
if present?(translation_caller)
|
126
|
-
find_lookup_scope(translation_caller)
|
127
|
-
else
|
128
|
-
nil
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def calling_template(string)
|
133
|
-
string.match(/(views)(\/.+)(?>:[0-9]+:in)/)
|
134
|
-
end
|
135
|
-
|
136
90
|
def blank?(str)
|
137
|
-
raise "blank?(str) can only be given a String or nil" unless str.is_a?(String)
|
138
|
-
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 == ""
|
139
93
|
end
|
140
94
|
|
141
95
|
def present?(str)
|
142
|
-
raise "present?(str) can only be given a String or nil" unless str.is_a?(String)
|
143
|
-
|
144
|
-
end
|
145
|
-
|
146
|
-
def find_lookup_scope(caller)
|
147
|
-
split_path = caller[2][1..-1].split(".")[0].split("/")
|
148
|
-
|
149
|
-
template_or_partial = remove_underscore_form_partial(split_path[-1])
|
150
|
-
split_path[-1] = template_or_partial
|
151
|
-
|
152
|
-
split_path.map!(&:to_sym)
|
153
|
-
end
|
154
|
-
|
155
|
-
def remove_underscore_form_partial(template_or_partial)
|
156
|
-
if template_or_partial.to_s[0,1] == "_"
|
157
|
-
template_or_partial.to_s[1..-1]
|
158
|
-
else
|
159
|
-
template_or_partial.to_s
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
def api_wrapper
|
164
|
-
@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)
|
165
98
|
end
|
166
99
|
end
|
167
100
|
end
|
@@ -1,62 +1,39 @@
|
|
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
|
-
suffix: "__}}"
|
13
|
-
api_host: "https://api.phrase.com",
|
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: [],
|
11
|
+
suffix: "__}}"
|
21
12
|
}.freeze
|
22
13
|
|
23
|
-
CONFIG_OPTIONS_GLOBAL_ONLY = [
|
24
|
-
:access_token,
|
25
|
-
:skip_ssl_verification,
|
26
|
-
:api_host
|
27
|
-
].freeze
|
28
|
-
|
29
14
|
CONFIG_OPTIONS.each do |option, default_value|
|
30
|
-
class_eval "@@#{option} = CONFIG_OPTIONS[:#{option}]"
|
15
|
+
class_eval "@@#{option} = CONFIG_OPTIONS[:#{option}]", __FILE__, __LINE__
|
31
16
|
|
32
17
|
define_method("#{option}=") do |value|
|
33
|
-
instance_eval "@#{option} = value
|
34
|
-
end
|
18
|
+
instance_eval "@#{option} = value", __FILE__, __LINE__
|
19
|
+
end
|
35
20
|
|
36
|
-
define_method(
|
37
|
-
instance_eval "defined?(@#{option}) ? @#{option} : self.class.#{option}"
|
21
|
+
define_method(option.to_s) do
|
22
|
+
instance_eval "defined?(@#{option}) ? @#{option} : self.class.#{option}", __FILE__, __LINE__
|
38
23
|
end
|
39
24
|
|
40
25
|
define_singleton_method("#{option}=") do |value|
|
41
|
-
instance_eval "@@#{option} = value
|
26
|
+
instance_eval "@@#{option} = value", __FILE__, __LINE__
|
42
27
|
end
|
43
28
|
|
44
|
-
define_singleton_method(
|
45
|
-
instance_eval "@@#{option}"
|
29
|
+
define_singleton_method(option.to_s) do
|
30
|
+
instance_eval "@@#{option}", __FILE__, __LINE__
|
46
31
|
end
|
47
32
|
end
|
48
33
|
|
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={})
|
34
|
+
def assign_values(config_options = {})
|
58
35
|
config_options.each do |config_option, value|
|
59
|
-
|
36
|
+
send("#{config_option}=", value)
|
60
37
|
end
|
61
38
|
end
|
62
39
|
|
@@ -65,20 +42,6 @@ module PhraseApp
|
|
65
42
|
send("#{option}=", default_value)
|
66
43
|
end
|
67
44
|
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
45
|
end
|
83
46
|
end
|
84
47
|
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
|
@@ -1,17 +1,15 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
|
-
|
3
1
|
module PhraseApp
|
4
2
|
module InContextEditor
|
5
3
|
module Delegate
|
6
4
|
class Base < String
|
7
5
|
def to_s
|
8
|
-
|
6
|
+
decorated_key_name.to_s
|
9
7
|
end
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
alias_method :camelize, :to_s
|
9
|
+
alias_method :underscore, :to_s
|
10
|
+
alias_method :classify, :to_s
|
11
|
+
alias_method :dasherize, :to_s
|
12
|
+
alias_method :tableize, :to_s
|
15
13
|
|
16
14
|
# Delegate .html_safe from accessing Delegate object as if it was a hash,
|
17
15
|
# but instead perform it on the resulting string
|
@@ -19,23 +17,24 @@ module PhraseApp
|
|
19
17
|
|
20
18
|
def self.log(message)
|
21
19
|
message = "phrase: #{message}"
|
22
|
-
if defined?(Rails)
|
20
|
+
if defined?(Rails) && Rails.respond_to?(:logger)
|
23
21
|
Rails.logger.warn(message)
|
24
22
|
else
|
25
|
-
|
23
|
+
warn message
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
29
|
-
|
27
|
+
protected
|
28
|
+
|
30
29
|
def decorated_key_name
|
31
30
|
"#{PhraseApp::InContextEditor.prefix}phrase_#{normalized_display_key}#{PhraseApp::InContextEditor.suffix}"
|
32
31
|
end
|
33
32
|
|
34
33
|
def normalized_display_key
|
35
|
-
|
36
|
-
@display_key.gsub("<", "[[[[[[html_open]]]]]]").gsub(">", "[[[[[[html_close]]]]]]")
|
37
|
-
else
|
34
|
+
if @display_key.nil?
|
38
35
|
@display_key
|
36
|
+
else
|
37
|
+
@display_key.gsub("<", "[[[[[[html_open]]]]]]").gsub(">", "[[[[[[html_close]]]]]]")
|
39
38
|
end
|
40
39
|
end
|
41
40
|
end
|
@@ -1,14 +1,13 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
require 'i18n'
|
1
|
+
require "phraseapp-in-context-editor-ruby"
|
2
|
+
require "i18n"
|
4
3
|
|
5
4
|
if defined? Rails
|
6
5
|
module PhraseApp
|
7
6
|
module InContextEditor
|
8
7
|
class Engine < Rails::Engine
|
9
|
-
initializer
|
10
|
-
require
|
11
|
-
require
|
8
|
+
initializer "phraseapp-in-context-editor-ruby", before: :disable_dependency_loading do |app|
|
9
|
+
require "phraseapp-in-context-editor-ruby/adapters/i18n"
|
10
|
+
require "phraseapp-in-context-editor-ruby/adapters/fast_gettext"
|
12
11
|
|
13
12
|
ActionView::Base.send :include, PhraseApp::InContextEditor::ViewHelpers
|
14
13
|
end
|