translation_center 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -68,6 +68,11 @@ And run the migrations
68
68
  rake db:migrate
69
69
  ```
70
70
 
71
+ And then run this rake to get all current translations to the db
72
+ ```ruby
73
+ rake translation_center:synch
74
+ ```
75
+
71
76
  In your User model or any other model that should acts as a translator add the following line:
72
77
 
73
78
  ```ruby
@@ -31,7 +31,7 @@
31
31
  %li
32
32
  = format_change(change, value)
33
33
  %td
34
- = time_ago_in_words change.created_at
34
+ = distance_of_time_in_words_to_now change.created_at
35
35
  = t('.ago')
36
36
 
37
37
  = will_paginate translations_changes
@@ -8,7 +8,7 @@
8
8
 
9
9
  - if translation_admin?
10
10
  %div
11
- = link_to '×', translation_key_path(translation_key), method: :delete, data: { confirm: t('actions.are_you_sure', :default => 'Are you sure?') }, class: 'close', remote: true
11
+ = link_to '×', translation_key_path(translation_key), method: :delete, data: { confirm: t('translation_center.actions.are_you_sure', :default => 'Are you sure?') }, class: 'close', remote: true
12
12
 
13
13
  %a{ href: "##{translation_key.id}", 'data-toggle' => "tab"}
14
14
  %p
@@ -17,7 +17,7 @@
17
17
  = t(translation_key.name)
18
18
  %span
19
19
  %em.created_time
20
- = t('.created_at')
20
+ = t('.created_on')
21
21
  = format_date(translation_key.created_at)
22
22
 
23
23
  %small
@@ -3,6 +3,6 @@
3
3
  %h1
4
4
  = @translation_key.name
5
5
  - if translation_admin?
6
- = link_to t('.destroy'), @translation_key, method: :delete, data: { confirm: t('actions.are_you_sure', :default => 'Are you sure?') }, class: 'btn btn-danger'
6
+ = link_to t('.destroy'), @translation_key, method: :delete, data: { confirm: t('translation_center.actions.are_you_sure', :default => 'Are you sure?') }, class: 'btn btn-danger'
7
7
 
8
8
  = render 'translation_center/translation_keys/show', translation_key: @translation_key, index: 0
@@ -5,7 +5,7 @@
5
5
  = translation.value
6
6
 
7
7
  - if translation_admin?
8
- = link_to '×', translation_path(translation), method: :delete, data: { confirm: t('actions.are_you_sure', :default => 'Are you sure?') }, class: 'close', remote: true
8
+ = link_to '×', translation_path(translation), method: :delete, data: { confirm: t('translation_center.actions.are_you_sure', :default => 'Are you sure?') }, class: 'close', remote: true
9
9
  %br
10
10
  %small.pull-right
11
11
  %em
@@ -10,4 +10,10 @@ namespace :translation_center do
10
10
  TranslationCenter.db2yaml(args[:locale])
11
11
  end
12
12
 
13
+ desc "Calls yaml2db then db2yaml"
14
+ task :synch, [:locale ] => :environment do |t, args|
15
+ TranslationCenter.yaml2db(args[:locale])
16
+ TranslationCenter.db2yaml(args[:locale])
17
+ end
18
+
13
19
  end
@@ -1,5 +1,7 @@
1
1
  en:
2
- translation_center:
2
+ translation_center:
3
+ actions:
4
+ are_you_sure: "Are you sure ?"
3
5
  back_to_app: "Back To App"
4
6
  categories:
5
7
  category:
@@ -14,7 +16,7 @@ en:
14
16
  untranslated: Untranslated
15
17
  center:
16
18
  activity:
17
- ago: Ago
19
+ ago: ago
18
20
  changes: Changes
19
21
  key: Key
20
22
  locale: Locale
@@ -46,7 +48,7 @@ en:
46
48
  back_to_category: "Back To Category"
47
49
  destroy: Destroy
48
50
  show_keys:
49
- created_at: "created at"
51
+ created_on: "created on"
50
52
  translated: Translated
51
53
  translation_keys:
52
54
  no_translation_keys: "No Translation Keys"
@@ -59,7 +61,7 @@ en:
59
61
  votes: Votes
60
62
  show:
61
63
  by: by
62
- on_date: "on date"
64
+ on_date: "on"
63
65
  vote: Vote
64
66
  votes: Votes
65
67
  you: You
@@ -39,23 +39,43 @@ module TranslationCenter
39
39
  end
40
40
  end
41
41
 
42
+ # make sure the complete key is build using the options such as scope and count
43
+ def prepare_key(key, options)
44
+ complete_key = key
45
+
46
+ # if a scope is passed in options then build the full key
47
+ complete_key = options[:scope].present? ? "#{options[:scope].to_s}.#{complete_key}" : complete_key
48
+
49
+ # add the correct count suffix
50
+ if options[:count].present? && options[:count] == 1
51
+ complete_key = "#{complete_key}.one"
52
+ elsif options[:count].present? && options[:count] != 1
53
+ complete_key = "#{complete_key}.other"
54
+ end
55
+ complete_key
56
+ end
57
+
42
58
  def translate_with_adding(locale, key, options = {})
43
59
  # handle calling translation with a blank key
44
60
  # or translation center tables don't exist
45
61
  return translate_without_adding(locale, key, options) if key.blank? || !ActiveRecord::Base.connection.table_exists?('translation_center_translation_keys')
46
62
 
63
+ complete_key = prepare_key(key, options) # prepare complete key
64
+
47
65
  # add the new key or update it
48
- translation_key = TranslationCenter::TranslationKey.find_or_create_by_name(key)
66
+ translation_key = TranslationCenter::TranslationKey.find_or_create_by_name(complete_key)
49
67
  # UNCOMMENT THIS LATER TO SET LAST ACCESSED AT
50
68
  # translation_key.update_attribute(:last_accessed, Time.now)
51
69
 
52
- # save the default value (Which is the titleized key name as the translation)
53
- translation_key.create_default_translation if translation_key.translations.in(:en).empty? && TranslationCenter::CONFIG['save_default_translation']
70
+ # save the default value (Which is the titleized key name as the translation) if the option is enabled and no translation exists for that key in the db
71
+ translation_key.create_default_translation if TranslationCenter::CONFIG['save_default_translation'] && translation_key.translations.in(:en).empty?
54
72
 
55
73
  # if i18n_source is set to db and not overriden by options then fetch from db
56
74
  if TranslationCenter::CONFIG['i18n_source'] == 'db' && options.delete(:yaml).blank?
57
75
  val = translation_key.accepted_translation_in(locale).try(:value) || options[:default]
58
- throw(:exception, I18n::MissingTranslation.new(locale, key, options)) unless val
76
+ # replace variables in a translation with passed values
77
+ options.each_pair{ |key, value| val.gsub!("%{#{key.to_s}}", value.to_s) }
78
+ throw(:exception, I18n::MissingTranslation.new(locale, complete_key, options)) unless val
59
79
  wrap_span(val, translation_key)
60
80
  else
61
81
  # just return the normal I18n translation
@@ -1,33 +1,31 @@
1
1
  module TranslationCenter
2
2
 
3
-
4
-
5
- def self.yaml2db(locale)
6
-
7
- def self.collect_keys(scope, translations)
8
- full_keys = []
9
- translations.to_a.each do |key, translations|
10
- new_scope = scope.dup << key
11
- if translations.is_a?(Hash)
12
- full_keys += collect_keys(new_scope, translations)
13
- else
14
- full_keys << new_scope.join('.')
15
- end
16
- end
17
- return full_keys
3
+ # needed for interpolated translations in I18n
4
+ def self.get_translation_from_hash(key, hash)
5
+ path = key.split('.')
6
+ last_step = hash
7
+ path.each do |step|
8
+ break if last_step.blank? || !last_step.is_a?(Hash)
9
+ last_step = last_step[step.to_s.to_sym]
18
10
  end
11
+ last_step
12
+ end
19
13
 
20
- # needed for interpolated translations in I18n
21
- def self.get_translation_from_hash(key, hash)
22
- path = key.split('.')
23
- last_step = hash
24
- path.each do |step|
25
- break if last_step.blank? || !last_step.is_a?(Hash)
26
- last_step = last_step[step.to_s.to_sym]
14
+ def self.collect_keys(scope, translations)
15
+ full_keys = []
16
+ translations.to_a.each do |key, translations|
17
+ new_scope = scope.dup << key
18
+ if translations.is_a?(Hash)
19
+ full_keys += collect_keys(new_scope, translations)
20
+ else
21
+ full_keys << new_scope.join('.')
22
+ end
27
23
  end
28
- last_step
24
+ return full_keys
29
25
  end
30
26
 
27
+ def self.yaml2db(locale)
28
+
31
29
  # prepare translator by creating the translator if he doesn't exist
32
30
  translator = TranslationCenter.prepare_translator
33
31
 
@@ -1,3 +1,3 @@
1
1
  module TranslationCenter
2
- VERSION = "1.2.1"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  %table
4
4
  %tr
5
- %th Title
6
- %th Content
5
+ %th= t('.title')
6
+ %th= t('.content')
7
7
  %th
8
8
  %th
9
9
  %th
@@ -7,6 +7,8 @@
7
7
  %b Content:
8
8
  = @article.content
9
9
 
10
+ = time_ago_in_words @article.created_at
11
+
10
12
  = link_to 'Edit', edit_article_path(@article)
11
13
  \|
12
14
  = link_to 'Back', articles_path
@@ -0,0 +1,2 @@
1
+ ---
2
+ de: {}
@@ -1 +1,339 @@
1
+ ---
1
2
  en:
3
+ activerecord:
4
+ attributes: Attributes
5
+ errors:
6
+ messages:
7
+ record_invalid: "Validation failed: %{errors}"
8
+ taken: "has already been taken"
9
+ models: Models
10
+ date:
11
+ abbr_day_names:
12
+ - Sun
13
+ - Mon
14
+ - Tue
15
+ - Wed
16
+ - Thu
17
+ - Fri
18
+ - Sat
19
+ abbr_month_names:
20
+ - ~
21
+ - Jan
22
+ - Feb
23
+ - Mar
24
+ - Apr
25
+ - May
26
+ - Jun
27
+ - Jul
28
+ - Aug
29
+ - Sep
30
+ - Oct
31
+ - Nov
32
+ - Dec
33
+ day_names:
34
+ - Sunday
35
+ - Monday
36
+ - Tuesday
37
+ - Wednesday
38
+ - Thursday
39
+ - Friday
40
+ - Saturday
41
+ formats:
42
+ default: "%Y-%m-%d"
43
+ long: "%B %d, %Y"
44
+ short: "%b %d"
45
+ month_names:
46
+ - ~
47
+ - January
48
+ - February
49
+ - March
50
+ - April
51
+ - May
52
+ - June
53
+ - July
54
+ - August
55
+ - September
56
+ - October
57
+ - November
58
+ - December
59
+ order:
60
+ - !ruby/symbol year
61
+ - !ruby/symbol month
62
+ - !ruby/symbol day
63
+ datetime:
64
+ distance_in_words:
65
+ about_x_hours:
66
+ one: "about 1 hour"
67
+ other: "about %{count} hours"
68
+ about_x_months:
69
+ one: "about 1 month"
70
+ other: "about %{count} months"
71
+ about_x_years:
72
+ one: "about 1 year"
73
+ other: "about %{count} years"
74
+ almost_x_years:
75
+ one: "almost 1 year"
76
+ other: "almost %{count} years"
77
+ half_a_minute: "half a minute"
78
+ less_than_x_minutes:
79
+ one: "less than a minute"
80
+ other: "less than %{count} minutes"
81
+ less_than_x_seconds:
82
+ one: "less than 1 second"
83
+ other: "less than %{count} seconds"
84
+ over_x_years:
85
+ one: "over 1 year"
86
+ other: "over %{count} years"
87
+ x_days:
88
+ one: "1 day"
89
+ other: "%{count} days"
90
+ x_minutes:
91
+ one: "1 minute"
92
+ other: "%{count} minutes"
93
+ x_months:
94
+ one: "1 month"
95
+ other: "%{count} months"
96
+ x_seconds:
97
+ one: "1 second"
98
+ other: "%{count} seconds"
99
+ prompts:
100
+ day: Day
101
+ hour: Hour
102
+ minute: Minute
103
+ month: Month
104
+ second: Seconds
105
+ year: Year
106
+ devise:
107
+ confirmations:
108
+ confirmed: "Your account was successfully confirmed. You are now signed in."
109
+ send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
110
+ send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes."
111
+ failure:
112
+ already_authenticated: "You are already signed in."
113
+ inactive: "Your account was not activated yet."
114
+ invalid: "Invalid email or password."
115
+ invalid_token: "Invalid authentication token."
116
+ locked: "Your account is locked."
117
+ not_found_in_database: "Invalid email or password."
118
+ timeout: "Your session expired, please sign in again to continue."
119
+ unauthenticated: "You need to sign in or sign up before continuing."
120
+ unconfirmed: "You have to confirm your account before continuing."
121
+ mailer:
122
+ confirmation_instructions:
123
+ subject: "Confirmation instructions"
124
+ reset_password_instructions:
125
+ subject: "Reset password instructions"
126
+ unlock_instructions:
127
+ subject: "Unlock Instructions"
128
+ omniauth_callbacks:
129
+ failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
130
+ success: "Successfully authenticated from %{kind} account."
131
+ passwords:
132
+ no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
133
+ send_instructions: "You will receive an email with instructions about how to reset your password in a few minutes."
134
+ send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
135
+ updated: "Your password was changed successfully. You are now signed in."
136
+ updated_not_active: "Your password was changed successfully."
137
+ registrations:
138
+ destroyed: "Bye! Your account was successfully cancelled. We hope to see you again soon."
139
+ signed_up: "Welcome! You have signed up successfully."
140
+ signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
141
+ signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
142
+ signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please open the link to activate your account."
143
+ update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm link to finalize confirming your new email address."
144
+ updated: "You updated your account successfully."
145
+ sessions:
146
+ signed_in: "Signed in successfully."
147
+ signed_out: "Signed out successfully."
148
+ unlocks:
149
+ send_instructions: "You will receive an email with instructions about how to unlock your account in a few minutes."
150
+ send_paranoid_instructions: "If your account exists, you will receive an email with instructions about how to unlock it in a few minutes."
151
+ unlocked: "Your account has been unlocked successfully. Please sign in to continue."
152
+ errors:
153
+ format: "%{attribute} %{message}"
154
+ messages:
155
+ accepted: "must be accepted"
156
+ already_confirmed: "was already confirmed, please try signing in"
157
+ blank: "can't be blank"
158
+ confirmation: "doesn't match confirmation"
159
+ confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
160
+ empty: "can't be empty"
161
+ equal_to: "must be equal to %{count}"
162
+ even: "must be even"
163
+ exclusion: "is reserved"
164
+ expired: "has expired, please request a new one"
165
+ greater_than: "must be greater than %{count}"
166
+ greater_than_or_equal_to: "must be greater than or equal to %{count}"
167
+ inclusion: "is not included in the list"
168
+ invalid: "is invalid"
169
+ less_than: "must be less than %{count}"
170
+ less_than_or_equal_to: "must be less than or equal to %{count}"
171
+ not_a_number: "is not a number"
172
+ not_an_integer: "must be an integer"
173
+ not_found: "not found"
174
+ not_locked: "was not locked"
175
+ not_saved:
176
+ one: "1 error prohibited this %{resource} from being saved:"
177
+ other: "%{count} errors prohibited this %{resource} from being saved:"
178
+ odd: "must be odd"
179
+ too_long: "is too long (maximum is %{count} characters)"
180
+ too_short: "is too short (minimum is %{count} characters)"
181
+ wrong_length: "is the wrong length (should be %{count} characters)"
182
+ helpers:
183
+ select:
184
+ prompt: "Please select"
185
+ submit:
186
+ create: "Create %{model}"
187
+ submit: "Save %{model}"
188
+ update: "Update %{model}"
189
+ meta_search:
190
+ or: or
191
+ predicates:
192
+ contains: "%{attribute} contains"
193
+ does_not_contain: "%{attribute} doesn't contain"
194
+ does_not_end_with: "%{attribute} doesn't end with"
195
+ does_not_equal: "%{attribute} doesn't equal"
196
+ does_not_start_with: "%{attribute} doesn't start with"
197
+ ends_with: "%{attribute} ends with"
198
+ equals: "%{attribute} equals"
199
+ greater_than: "%{attribute} greater than"
200
+ greater_than_or_equal_to: "%{attribute} greater than or equal to"
201
+ in: "%{attribute} is one of"
202
+ is_blank: "%{attribute} is blank"
203
+ is_false: "%{attribute} is false"
204
+ is_not_null: "%{attribute} isn't null"
205
+ is_null: "%{attribute} is null"
206
+ is_present: "%{attribute} is present"
207
+ is_true: "%{attribute} is true"
208
+ less_than: "%{attribute} less than"
209
+ less_than_or_equal_to: "%{attribute} less than or equal to"
210
+ not_in: "%{attribute} isn't one of"
211
+ starts_with: "%{attribute} starts with"
212
+ number:
213
+ currency:
214
+ format:
215
+ delimiter: ","
216
+ format: "%u%n"
217
+ precision: 2
218
+ separator: "."
219
+ unit: $
220
+ format:
221
+ delimiter: ","
222
+ precision: 3
223
+ separator: "."
224
+ human:
225
+ decimal_units:
226
+ format: "%n %u"
227
+ units:
228
+ billion: Billion
229
+ million: Million
230
+ quadrillion: Quadrillion
231
+ thousand: Thousand
232
+ trillion: Trillion
233
+ format:
234
+ precision: 3
235
+ significant: true
236
+ strip_insignificant_zeros: true
237
+ storage_units:
238
+ format: "%n %u"
239
+ units:
240
+ byte:
241
+ one: Byte
242
+ other: Bytes
243
+ gb: GB
244
+ kb: KB
245
+ mb: MB
246
+ tb: TB
247
+ support:
248
+ array:
249
+ last_word_connector: ", and "
250
+ two_words_connector: " and "
251
+ words_connector: ", "
252
+ time:
253
+ am: am
254
+ formats:
255
+ default: "%a, %d %b %Y %H:%M:%S %z"
256
+ long: "%B %d, %Y %H:%M"
257
+ short: "%d %b %H:%M"
258
+ pm: pm
259
+ translation_center:
260
+ actions:
261
+ are_you_sure: "Are you sure ?"
262
+ back_to_app: "Back To App"
263
+ categories:
264
+ category:
265
+ complete: Complete
266
+ keys: Keys
267
+ index:
268
+ categories: Categories
269
+ show:
270
+ all: All
271
+ pending: Pending
272
+ translated: Translated
273
+ untranslated: Untranslated
274
+ center:
275
+ activity:
276
+ ago: ago
277
+ changes: Changes
278
+ key: Key
279
+ locale: Locale
280
+ time: Time
281
+ user: User
282
+ dashboard:
283
+ activity: Activity
284
+ all: All
285
+ controls: Controls
286
+ dashboard: Dashboard
287
+ language: Language
288
+ pending: Pending
289
+ progress: Progress
290
+ reset: Reset
291
+ search: Search
292
+ select_locale: "Select Locale"
293
+ these_actions_will_affect_existing_data: "These actions will affect existing data"
294
+ translated: Translated
295
+ untranslated: Untranslated
296
+ dashboard: Dashboard
297
+ search_keys: "Search Keys"
298
+ translate_to: "Translate To"
299
+ translation_center: "Translation Center"
300
+ translation_keys:
301
+ destroyed_successfully: "Destroyed Successfully"
302
+ show:
303
+ add_edit_translation: "Add/Edit Translation"
304
+ back_to_category: "Back To Category"
305
+ destroy: Destroy
306
+ translations: Translations
307
+ show_keys:
308
+ created_on: "created on"
309
+ translated: Translated
310
+ translation_keys:
311
+ no_translation_keys: "No Translation Keys"
312
+ translations:
313
+ accept_translation:
314
+ unaccept: Unaccept
315
+ index:
316
+ date: Date
317
+ sort_by: "Sort by"
318
+ votes: Votes
319
+ show:
320
+ by: by
321
+ on_date: "on"
322
+ vote: Vote
323
+ votes: Votes
324
+ you: You
325
+ will_paginate:
326
+ next_label: "Next &#8594;"
327
+ page_entries_info:
328
+ multi_page: "Displaying %{model} %{from} - %{to} of %{count} in total"
329
+ multi_page_html: "Displaying %{model} <b>%{from}&nbsp;-&nbsp;%{to}</b> of <b>%{count}</b> in total"
330
+ single_page:
331
+ one: "Displaying 1 %{model}"
332
+ other: "Displaying all %{count} %{model}"
333
+ zero: "No %{model} found"
334
+ single_page_html:
335
+ one: "Displaying <b>1</b> %{model}"
336
+ other: "Displaying <b>all&nbsp;%{count}</b> %{model}"
337
+ zero: "No %{model} found"
338
+ page_gap: "&hellip;"
339
+ previous_label: "&#8592; Previous"
@@ -22,7 +22,7 @@ development:
22
22
  # "missing" to inspect only untranslated keys
23
23
  # "all" to enable inspector for translated and untranslated keys
24
24
  # "off" to turn off keys inspector
25
- inspector: 'missing' # default missing
25
+ inspector: 'all' # default missing
26
26
 
27
27
  # I18n.translate source
28
28
  i18n_source: 'db' # can be db or yaml; default is yaml