Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce support for deprecating translation keys #490

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/i18n.rb
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ def translate(key = nil, *, throw: false, raise: false, locale: nil, **options)
end
alias :t :translate

def deprecate(deprecation)
config.deprecations[deprecation.keys.first.to_sym] = deprecation.values.first.to_sym
end

# Wrapper for <tt>translate</tt> that adds <tt>:raise => true</tt>. With
# this option, if no translation is found, it will raise <tt>I18n::MissingTranslationData</tt>
def translate!(key, options = EMPTY_HASH)
Expand Down
1 change: 1 addition & 0 deletions lib/i18n/backend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module Backend
autoload :CacheFile, 'i18n/backend/cache_file'
autoload :Cascade, 'i18n/backend/cascade'
autoload :Chain, 'i18n/backend/chain'
autoload :Deprecator, 'i18n/backend/deprecator'
autoload :Fallbacks, 'i18n/backend/fallbacks'
autoload :Flatten, 'i18n/backend/flatten'
autoload :Gettext, 'i18n/backend/gettext'
Expand Down
25 changes: 24 additions & 1 deletion lib/i18n/backend/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,30 @@ def translate(locale, key, options = EMPTY_HASH)
raise InvalidLocale.new(locale) unless locale
return nil if key.nil? && !options.key?(:default)

entry = lookup(locale, key, options[:scope], options) unless key.nil?
entry = nil

unless key.nil?
normalized_key = I18n.normalize_keys(locale, key, options[:scope])[1..-1].join(I18n.config.default_separator).to_sym
deprecated_key = I18n.config.deprecations.key(normalized_key)

# Does this key supersede a deprecated one?
if deprecated_key
# Try to use up the old key, if present.
entry = lookup(locale, deprecated_key, nil, options)
end

entry ||= lookup(locale, key, options[:scope], options)

if entry.nil?
# Is this key deprecated by another?
new_key = I18n.config.deprecations[normalized_key]

if new_key
puts "DEPRECATION WARNING: #{normalized_key} is deprecated, use #{new_key} instead"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using warn (printing to stderr) instead of puts, as it is more common for deprecations.
You might also want to use warn(…, uplevel: 1) for rubies that support it, but you need to weight the checks on ruby version vs. the usability improvement of knowing when the error is originated.

entry = lookup(locale, new_key, nil, options)
end
end
end

if entry.nil? && options.key?(:default)
entry = default(locale, key, options[:default], options)
Expand Down
17 changes: 17 additions & 0 deletions lib/i18n/backend/deprecator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

module I18n
module Backend
module Deprecator
def store_translations(locale, data, options = EMPTY_HASH)
super

I18n.config.deprecations.each do |deprecated_key, new_key|
if lookup(locale, deprecated_key)
puts "DEPRECATION WARNING: #{deprecated_key} is deprecated, use #{new_key} instead"
end
end
end
end
end
end
4 changes: 4 additions & 0 deletions lib/i18n/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ def backend=(backend)
@@backend = backend
end

def deprecations
@@deprecations ||= {}
end

# Returns the current default locale. Defaults to :'en'
def default_locale
@@default_locale ||= :en
Expand Down
35 changes: 35 additions & 0 deletions test/backend/deprecator_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require 'test_helper'

class I18nBackendDeprecatorTest < I18n::TestCase
class Backend < I18n::Backend::Simple
include I18n::Backend::Deprecator
include I18n::Backend::Fallbacks
end

def setup
super
I18n.backend = Backend.new
I18n.deprecate(old_key: :new_key)
end

test 'old key defined, new key undefined' do
store_translations(:xx, old_key: 'Hello world')

assert_equal 'Hello world', I18n.t(:old_key, locale: :xx)
assert_equal 'Hello world', I18n.t(:new_key, locale: :xx)
end

test 'old key undefined, new key defined' do
store_translations(:xx, new_key: 'Hello new world')

assert_equal 'Hello new world', I18n.t(:old_key, locale: :xx)
assert_equal 'Hello new world', I18n.t(:new_key, locale: :xx)
end

test 'old key defined, new key defined' do
store_translations(:xx, old_key: 'Hello world', new_key: 'Hello new world')

assert_equal 'Hello world', I18n.t(:old_key, locale: :xx)
assert_equal 'Hello world', I18n.t(:new_key, locale: :xx)
end
end