Skip to content

Commit

Permalink
Add option to enforce translations
Browse files Browse the repository at this point in the history
  • Loading branch information
Nerian committed Mar 9, 2023
1 parent 921ce9c commit f6f6fc8
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* Remove test files from the gem package. [@orien](https://github.com/orien)
* Speed up input mapping lookup by avoiding rescuing exceptions. [@meanphil](https://github.com/meanphil) [@kriom](https://github.com/kriom) [@egeek](https://github.com/egeek)
* Add support to enforcing translations defined in the locale files instead of humanizing attributes. [@Nerian](https://github.com/Nerian)

## 5.2.0

Expand Down
5 changes: 5 additions & 0 deletions lib/simple_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@ def self.configured? #:nodoc:
mattr_accessor :input_field_valid_class
@@input_field_valid_class = nil

# If set to true all labels, hints, and placeholders would be expected to have an entry in a locale file and raise
# an exception if not.
mattr_accessor :enforce_translations
@@enforce_translations = false

# Retrieves a given wrapper
def self.wrapper(name)
@@wrappers[name.to_s] or raise WrapperNotFound, "Couldn't find wrapper with name #{name}"
Expand Down
4 changes: 1 addition & 3 deletions lib/simple_form/components/labels.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,8 @@ def required_label_text #:nodoc:

# First check labels translation and then human attribute name.
def label_translation #:nodoc:
if SimpleForm.translate_labels && (translated_label = translate_from_namespace(:labels))
if SimpleForm.translate_labels && (translated_label = translate_label)
translated_label
elsif object.class.respond_to?(:human_attribute_name)
object.class.human_attribute_name(reflection_or_attribute_name.to_s)
else
attribute_name.to_s.humanize
end
Expand Down
40 changes: 40 additions & 0 deletions lib/simple_form/inputs/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,46 @@ def translate_from_namespace(namespace, default = '')
I18n.t(lookups.shift, scope: :"#{i18n_scope}.#{namespace}", default: lookups).presence
end

def translate_label(namespace = :labels, default = '')
model_names = lookup_model_names.dup
lookups = []

while !model_names.empty?
joined_model_names = model_names.join(".")
model_names.shift

lookups << :"#{joined_model_names}.#{lookup_action}.#{reflection_or_attribute_name}"
lookups << :"#{joined_model_names}.#{reflection_or_attribute_name}"
end
lookups << :"defaults.#{lookup_action}.#{reflection_or_attribute_name}"
lookups << :"defaults.#{reflection_or_attribute_name}"

lookups = lookups.map { |l| :"#{i18n_scope}.#{namespace}.#{l}" }

if object.class.respond_to?(:human_attribute_name)
attribute = reflection_or_attribute_name.to_s
klass_scope = object.class.i18n_scope
if attribute.include?(".")
namespace, _, attribute = attribute.rpartition(".")
namespace.tr!(".", "/")

object.class.lookup_ancestors.map do |klass|
lookups << :"#{klass_scope}.attributes.#{klass.model_name.i18n_key}/#{namespace}.#{attribute}"
end
lookups << :"#{klass_scope}.attributes.#{namespace}.#{attribute}"
else
object.class.lookup_ancestors.map do |klass|
lookups << :"#{klass_scope}.attributes.#{klass.model_name.i18n_key}.#{attribute}"
end
end
lookups << :"#{klass_scope}.attributes.#{attribute}"
end


lookups << default unless SimpleForm.enforce_translations
I18n.t(lookups.shift, default: lookups, raise: SimpleForm.enforce_translations).presence
end

def merge_wrapper_options(options, wrapper_options)
if wrapper_options
wrapper_options = set_input_classes(wrapper_options)
Expand Down
14 changes: 12 additions & 2 deletions test/components/label_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ def with_label_for(object, attribute_name, type, options = {})

test 'label uses human attribute name from object when available' do
with_label_for @user, :description, :text
assert_select 'label[for=user_description]', /User Description!/
assert_select 'label[for=user_description]', /Description/
end

test 'label uses human attribute name based on association name' do
with_label_for @user, :company_id, :string, setup_association: true
assert_select 'label', /Company Human Name!/
assert_select 'label', /Company/
end

test 'label uses i18n based on model, action, and attribute to lookup translation' do
Expand Down Expand Up @@ -85,6 +85,16 @@ def @controller.action_name; nil; end
end
end

test 'missing translation in location file raises exception if SimpleForm.enforce_translations is true' do
swap SimpleForm, enforce_translations: true do
store_translations(:en, simple_form: { }) do
assert_raise I18n::MissingTranslationData do
with_label_for @user, :age, :integer
end
end
end
end

test 'label uses i18n with lookup for association name' do
store_translations(:en, simple_form: { labels: {
user: { company: 'My company!' }
Expand Down
1 change: 1 addition & 0 deletions test/support/models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def group_method

class User
extend ActiveModel::Naming
extend ActiveModel::Translation
include ActiveModel::Conversion

attr_accessor :id, :name, :company, :company_id, :time_zone, :active, :age,
Expand Down

0 comments on commit f6f6fc8

Please sign in to comment.