Module: Yast::I18n

Included in:
Builtins, Client, Module
Defined in:
src/ruby/yast/i18n.rb

Overview

Provides translation wrapper.

Constant Summary collapse

DEFAULT_LOCALE =

if every heuristic fails then use the default for locale

"en_US".freeze

Instance Method Summary collapse

Instance Method Details

#_(str) ⇒ String

Note:

⚠ The translated string is frozen and cannot be modified. To provide consistent results the original (not translated) string is also frozen. This means this function modifies the passed argument! If you do not want this behavior then pass a duplicate, e.g. _(text.dup). ⚠

translates given string

Parameters:

  • str (String)

    the string to translate

Returns:

  • (String)

    the translated string, if the translation is not found then the original text is returned. The returned String is frozen!



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'src/ruby/yast/i18n.rb', line 53

def _(str)
  # no textdomain configured yet
  if !@my_textdomain
    if File.exist?(LOCALE_DIR)
      msg = "No textdomain configured in #{self.class}, " \
            "cannot translate #{str.inspect}"
      raise msg if ENV["Y2STRICTTEXTDOMAIN"]
      Yast.y2warning(1, "%1", msg) # skip 1 frame
    end
    return str.freeze
  end

  found = true
  # Switching textdomain clears gettext caches so avoid it if possible.
  if !@my_textdomain.include?(FastGettext.text_domain) || !key_exist?(str)
    # Set domain where key is defined.
    found = @my_textdomain.any? do |domain|
      FastGettext.text_domain = domain
      key_exist?(str)
    end
  end
  found ? Translation._(str) : str.freeze
end

#N_(str) ⇒ Object

No translation, only marks the text to be found by gettext when creating POT file, the text needs to be translated by #_ later.

Examples:

Error messages

begin
  # does not translate, the exception contains the untranslated string,
  # but it's recognized by gettext like normal _()
  raise FooError, N_("Foo failed.")
rescue FooError => e
  # log the original (untranslated) error
  log.error e.message

  # but display translated error to the user,
  # _() does the actual translation
  Popup.Error(_(e.message))
end

Translating Constants

class Foo
  # ERROR_MSG will not be translated, but the string will be found
  # by gettext when creating the POT file
  ERROR_MSG = N_("Something failed")
end

# here the string will be translated using the current locale
puts _(Foo::ERROR_MSG)


104
105
106
# File 'src/ruby/yast/i18n.rb', line 104

def N_(str)
  str
end

#n_(singular, plural, num) ⇒ String

Note:

⚠ The translated string is frozen and cannot be modified. To provide consistent results the original (not translated) strings are also frozen. This means this function modifies the passed argument! If you do not want this behavior then pass a duplicate, e.g. n_(singular.dup, plural.dup, n). ⚠

Gets translation based on number.

Parameters:

  • singular (String)

    text for translators for single value

  • plural (String)

    text for translators for bigger value

  • num (String)

    the actual number, used for evaluating the correct plural form

Returns:

  • (String)

    the translated string, if the translation is not found then the original text is returned (either the plural or the singular version, depending on the num parameter). The returned String is frozen!



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'src/ruby/yast/i18n.rb', line 125

def n_(singular, plural, num)
  # no textdomain configured yet
  if !@my_textdomain
    if File.exist?(LOCALE_DIR)
      # it's enough to log just the singular form
      msg = "No textdomain configured in #{self.class}, " \
            "cannot translate #{singular.inspect}"
      raise msg if ENV["Y2STRICTTEXTDOMAIN"]
      Yast.y2warning(1, "%1", msg) # skip 1 frame
    end
    return fallback_n_(singular, plural, num)
  end

  # Switching textdomain clears gettext caches so avoid it if possible.
  # difference between _ and n_ is hat we need special cache for plural forms
  found = true
  if !@my_textdomain.include?(FastGettext.text_domain) || !cached_plural_find(singular, plural)
    # Set domain where key is defined.
    found = @my_textdomain.any? do |domain|
      FastGettext.text_domain = domain
      cached_plural_find(singular, plural)
    end
  end
  found ? Translation.n_(singular, plural, num) : fallback_n_(singular, plural, num)
end

#Nn_(*keys) ⇒ Object

No translation, only marks the texts to be found by gettext when creating POT file, the texts need to be translated by #n_ later.



110
111
112
# File 'src/ruby/yast/i18n.rb', line 110

def Nn_(*keys)
  keys
end

#textdomain(domain) ⇒ Object

sets new text domain



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'src/ruby/yast/i18n.rb', line 16

def textdomain(domain) # usually without brackets like textdomain "example"
  # initialize FastGettext only if the locale directory exists
  return unless File.exist? LOCALE_DIR

  # FastGettext does not track which file/class uses which text domain,
  # it has just single global text domain (the current one),
  # remember the requested text domain here
  # One object can have multiple text domains via multiple Yast.include (bnc#877687).
  @my_textdomain ||= []
  @my_textdomain << domain unless @my_textdomain.include? domain

  # initialize available locales at first use or when the current language is changed
  if FastGettext.available_locales.nil? || current_language != FastGettext.locale
    available = available_locales
    if FastGettext.available_locales != available
      # reload the translations, a new language is available
      FastGettext.translation_repositories.keys.each do |dom|
        FastGettext.add_text_domain(dom, path: LOCALE_DIR)
      end
      FastGettext.available_locales = available
    end

    FastGettext.set_locale current_language
  end

  # add the text domain (only if missing to avoid re-reading translations)
  FastGettext.add_text_domain(domain, path: LOCALE_DIR) unless FastGettext.translation_repositories[domain]
end