module AnnoTranslate
Extentions to make internationalization (i18n) of a Rails application simpler. Support the method translate
(or shorter t
) in models/view/controllers/mailers.
Constants
- VERSION
Public Class Methods
When fallback mode is enabled if a key cannot be found in the set locale, it uses the default locale. So, for example, if an app is mostly localized to Spanish (:es), but a new page is added then Spanish users will continue to see mostly Spanish content but the English version (assuming the default_locale
is :en) for the new page that has not yet been translated to Spanish.
# File lib/annotranslate.rb, line 169 def self.fallback(enable = true) @@fallback_mode = enable end
If fallback mode is enabled
# File lib/annotranslate.rb, line 174 def self.fallback? @@fallback_mode end
Plugin-specific Rails logger
# File lib/annotranslate.rb, line 38 def self.log # Create logger if it doesn't exist yet if @@logger.nil? log_file = Rails.root.join('log', 'annotranslate.log').to_s puts "AnnoTranslate is logging to: #{log_file}" @@logger = Logger.new(File.open(log_file, "w", encoding: 'UTF-8')) @@logger.info "Started new AnnoTranslate logging session!" end # Return the logger instance @@logger end
Pseudo-translation text to append to fetched strings. Used as a visible marker. Default is “]]”
# File lib/annotranslate.rb, line 224 def self.pseudo_append @@pseudo_append end
Set the pseudo-translation text to append to fetched strings. Used as a visible marker.
# File lib/annotranslate.rb, line 230 def self.pseudo_append=(v) @@pseudo_append = v end
Pseudo-translation text to prepend to fetched strings. Used as a visible marker. Default is “[[”
# File lib/annotranslate.rb, line 212 def self.pseudo_prepend @@pseudo_prepend end
Set the pseudo-translation text to prepend to fetched strings. Used as a visible marker.
# File lib/annotranslate.rb, line 218 def self.pseudo_prepend=(v) @@pseudo_prepend = v end
Toggle a pseudo-translation mode that will prepend / append special text to all fetched strings. This is useful during testing to view pages and visually confirm that strings have been fully extracted into locale bundles.
# File lib/annotranslate.rb, line 201 def self.pseudo_translate(enable = true) @@pseudo_translate = enable end
If pseudo-translated is enabled
# File lib/annotranslate.rb, line 206 def self.pseudo_translate? @@pseudo_translate end
# File lib/annotranslate.rb, line 139 def self.scope_key_by_partial(key, path) if key.to_s.first == "." if path path.gsub(%r{/_?}, ".") + key.to_s else error = "Cannot use t(#{key.inspect}) shortcut because path is not available" AnnoTranslate.log.error error raise error end else key end end
Set an optional block that gets called when there’s a missing translation within a view. This can be used to log missing translations in production.
Block takes two required parameters:
-
exception (original I18n::MissingTranslationData that was raised for the failed translation)
-
key (key that was missing)
-
options (hash of options sent to annotranslate)
Example:
set_missing_translation_callback do |ex, key, options| logger.info("Failed to find #{key}") end
# File lib/annotranslate.rb, line 76 def self.set_missing_translation_callback(&block) @@missing_translation_callback = block end
Toggle whether to true an exception on all MissingTranslationData
exceptions Useful during testing to ensure all keys are found. Passing true
enables strict mode, false
installs the default exception handler which does not raise on MissingTranslationData
# File lib/annotranslate.rb, line 182 def self.strict_mode(enable_strict = true) @@strict_mode = enable_strict if enable_strict # Switch to using contributed exception handler I18n.exception_handler = :strict_i18n_exception_handler else I18n.exception_handler = :default_exception_handler end end
Get if it is in strict mode
# File lib/annotranslate.rb, line 194 def self.strict_mode? @@strict_mode end
# File lib/annotranslate.rb, line 56 def self.tag_helper TagHelper.instance end
Generic translate method that mimics I18n.translate
(e.g. no automatic scoping) but includes locale fallback and strict mode behavior.
# File lib/annotranslate.rb, line 157 def translate(key, options={}) AnnoTranslate.translate_with_annotation(key, @virtual_path, options) end
# File lib/annotranslate.rb, line 80 def self.translate_with_annotation(scope, path, key, options={}) AnnoTranslate.log.info "translate_with_annotation(scope=#{scope}, path=#{path}, key=#{key}, options=#{options.inspect})" scope ||= [] # guard against nil scope # Let Rails 2.3 handle keys starting with "." # raise AnnoTranslateError, "Skip keys with leading dot" if key.to_s.first == "." # Keep the original options clean original_scope = scope.dup scoped_options = {}.merge(options) # Raise to know if the key was found scoped_options[:raise] = true # Remove any default value when searching with scope scoped_options.delete(:default) str = nil # the string being looked for # Apply scoping to partial keys key = AnnoTranslate.scope_key_by_partial(key, path) # Loop through each scope until a string is found. # Example: starts with scope of [:blog_posts :show] then tries scope [:blog_posts] then # without any automatically added scope ("[]"). while str.nil? # Set scope to use for search scoped_options[:scope] = scope begin # try to find key within scope (dup the options because I18n modifies the hash) str = I18n.translate(key, scoped_options.dup) rescue I18n::MissingTranslationData => exc # did not find the string, remove a layer of scoping. # break when there are no more layers to remove (pop returns nil) break if scope.pop.nil? end end # If a string is not yet found, potentially check the default locale if in fallback mode. if str.nil? && AnnoTranslate.fallback? && (I18n.locale != I18n.default_locale) && options[:locale].nil? # Recurse original request, but in the context of the default locale str ||= AnnoTranslate.translate_with_scope(original_scope, key, options.merge({:locale => I18n.default_locale})) end # If a string was still not found, fall back to trying original request (gets default behavior) str ||= I18n.translate(key, options) # If pseudo-translating, prepend / append marker text if AnnoTranslate.pseudo_translate? && !str.nil? str = AnnoTranslate.pseudo_prepend + str + AnnoTranslate.pseudo_append end tag = tag_helper.content_tag('span', str, :class => 'translation_annotated', :title => key) AnnoTranslate.log.info " => full_key=#{key}, translation=#{str}, tag=#{tag.inspect}" tag end