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

Add option to enforce translations #1813

Open
wants to merge 1 commit into
base: main
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
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
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
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
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
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
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