Class: RuboCop::Cop::DevDoc::I18n::TranslationKeyPrefix

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/dev_doc/i18n/translation_key_prefix.rb

Overview

Require translation keys to start with an allowed namespace prefix.

Rationale

A flat translation catalog drifts into collisions and dead keys. Requiring every t(...) key to start with an agreed namespace (e.g. hotel., general.) keeps the locale files organized and makes it obvious which feature owns a key.

The allowed prefixes are project-specific, so AllowedPrefixes: defaults to empty and the cop does nothing until a project configures it. Matches t, translate, and I18n.t (the receiver is ignored).

Only statically-literal keys are checked. A key built from interpolation (t("#{prefix}.foo")) or a variable (t(key)) can't be verified and is skipped. A key that begins with a literal segment (t("hotel.#{id}")) is checked against that leading segment.

 No recognized prefix
t('welcome.title')

✔️ Namespaced
t('general.welcome.title')
t('hotel.rooms.heading')

Examples:

AllowedPrefixes: ['hotel.', 'general.']

# bad
t('welcome.title')

# bad (lazy key has no namespace)
t('.title')

# good
t('hotel.rooms.heading')

# good (variable suffix, literal prefix is checked)
t("general.#{key}")

# not checked (fully dynamic key)
t("#{prefix}.title")

Constant Summary collapse

MSG =
'Translation key `%<key>s` must start with an allowed ' \
'prefix: %<prefixes>s.'.freeze
RESTRICT_ON_SEND =
%i[t translate].freeze

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/rubocop/cop/dev_doc/i18n/translation_key_prefix.rb', line 50

def on_send(node)
  prefixes = allowed_prefixes
  return if prefixes.empty?

  key_node = node.first_argument
  return unless key_node

  leading = leading_literal(key_node)
  return if leading.nil?
  return if prefixes.any? { |prefix| leading.start_with?(prefix) }

  add_offense(key_node, message: format(MSG, key: key_node.source, prefixes: prefixes_display(prefixes)))
end