1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
- # This file collects a few Rails extensions to make it possible to translate both
- # errors built into Rails or other gems, and also our custom errors in the Zammad codebase.
- #
- # It works generally like this:
- # - The zammad:translation_catalog generator has an extractor that will find error message strings
- # defined by Rails and other gems and put them into the catalog of translatable strings.
- # - The I18n gem is extended to perform the actual translation lookups via the Zammad Translations API.
- #
- # Ensure the error message hash is loaded, as the code below relies on it.
- I18n.eager_load!
- module ActiveModel
- class Error
- # Make it possible to retrieve errors that are translated with a Zammad locale.
- # no_field_name indicates that the default behaviour of Rails which includes the field name
- # in the error message should be modified to say "This field ..." rather than "#{fieldname} ...".
- def localized_full_message(locale:, no_field_name: false)
- override_errors_format(locale, no_field_name) do
- ::I18n.with_zammad_locale(locale) do
- full_message
- end
- end
- end
- private
- def override_errors_format(locale, no_field_name)
- errors_hash = ::I18n.backend.translations[:en][:errors]
- orig_format = errors_hash[:format]
- errors_hash[:format] = ::Translation.translate(locale, 'This field %s', '%{message}') if no_field_name
- yield
- ensure
- errors_hash[:format] = orig_format
- end
- end
- class Errors
- if !method_defined?(:orig_add)
- alias orig_add add
- # This will add custom string errors to the I18n translation store.
- def add(attribute, type = :invalid, **options)
- return orig_add(attribute, type, **options) if !type.is_a?(String)
- # I18n uses namespacing to access the messages, so generate a safe symbol without the namespace separator '.'.
- type_sym = type.gsub(%r{\W}, '').to_sym
- ::I18n.backend.translations[:en][:errors][:messages][type_sym] = type
- orig_add(attribute, type_sym, **options)
- end
- end
- end
- end
- module I18n
- def self.with_zammad_locale(locale)
- backend.zammad_locale = locale
- yield
- ensure
- backend.zammad_locale = nil
- end
- end
- class I18n::Backend::Simple
- attr_accessor :zammad_locale
- if !method_defined?(:orig_lookup)
- alias orig_lookup lookup
- # Allow I18n to load the default rails error messages from the YAML files,
- # but translate them to the target locale before the error messages get generated
- # including placeholder subsitition.
- def lookup(...)
- result = orig_lookup(...)
- if result.is_a?(String) && zammad_locale
- return Translation.translate(zammad_locale, result)
- end
- result
- end
- end
- end
|