Class: Zen::Language
- Inherits:
-
Object
- Object
- Zen::Language
- Includes:
- Ramaze::Optioned, Validation
- Defined in:
- lib/zen/language.rb,
lib/zen/language/translation.rb
Overview
Zen::Language is the heart of the multi language system that comes with
Zen. It makes it easy to display localized bits of text as well as adding
new collections of translated strings.
Adding Languages
Adding a new language can be done by using Language.add. This method works similar to the ones used by Package and Theme. An example of adding a language (English in this case) looks like the following:
Zen::Language.add do |lang|
lang.name = 'en'
lang.title = 'English'
end
When adding a language you must set the following items:
- name: the language code as defined in ISO 639. Examples of these codes are "en-GB", "nl", etc. At the moment Zen does not have different language files for British English and American English.
- title: the name of the language in a human friendly form. This name should be set in the specific language. For example, for Dutch the title would be "Nederlands".
Optionally you can also set the following attributes:
- rtl: indicates that the language reads from right to left. When set to
true the
<html>tag will have an extradirattribute so that browsers can properly display the text from right to left.
Adding Translations
Translations for a certain language are added using
Translation. Similar to languages these are added by
calling .add(). A simple example of adding a set of translations is the
following:
Zen::Language::Translation.add do |trans|
trans.language = 'en'
trans.name = 'foobar'
trans.translate do |t|
end
end
This adds a language collection called "foobar" for the English language.
Translation strings are added inside the block of the translate()
method. Setting these strings works just like setting the keys and values of
a hash:
trans.translate do |t|
t['hello'] = 'Hello World'
end
It is a good idea to group certain language strings together. For example, you might have a few strings related to page titles. The way of doing this is by simply separating groups with a dot in the keys:
trans.translate do |t|
t['titles.index'] = 'Example'
t['titles.edit'] = 'Edit Example'
end
The keys specified in []= should match the regular expression as defined
in Translation::KEY_REGEX. In plain English, they can only
contain lower case letters, underscores and dots.
A full example:
Zen::Language::Translation.add do |trans|
trans.language = 'en'
trans.name = 'foobar'
trans.translate do |t|
t['titles.index'] = 'Example'
t['titles.edit'] = 'Edit Example'
end
end
Organizing Languages
In order for language files to be loaded by Zen you need to place them in
certain directories using a certain file name. Language files should be
named after the name setter/getter defined when calling
Translation.add (including casing) and should have .rb
as extension. These files should be placed in sub directories that match the
language name they belong to. These directories in turn should be placed
inside a "language" directory.
In other words, our "foobar" example would be stored as following:
language/
|
|__ en/
|
|__ foobar.rb
Before you can load files from the language directory you'll need to add it to the list of directories to search each time a language file is loaded. Similar to how you can add view folders or helper folders in Ramaze you can add language folders:
Zen::Language..paths << 'path/to/language'
Loading Translations
Once a language file has been added it must be loaded before it can be used. Loading a language file can be done in two ways:
- Manually loading it by calling Language.load.
- Calling lang or
lang()(injected into the global namespace).
In the last case missing language files will be loaded if possible. However, it is recommended that you pre-load your language files before starting the application. By doing this these translations don't have to be loaded during an HTTP request which could potentially slow down the application.
If we wanted to load the "foobar" language file mentioned earlier you can do this as following:
Zen::Language.load('foobar')
Using Translations
Once the entire process of adding and loading a language file has been
completed you can use the language strings defined in that file. This can be
done by calling the global method lang() which is available in all
scopes. If you happen to need it in a scope where it's overwritten you can
call lang instead.
A simple example of loading a few language strings of the file defined earlier in this guide looks like this:
lang('foobar.titles.index')
Language keys should always be in the format of A.B where A is the
name of the language file ("foobar" in this case) and B a dot separated
string that points to the language string to load. This means that the
following examples are not valid:
lang('foobar')
lang('foo bar')
Defined Under Namespace
Modules: SingletonMethods Classes: Translation
Constant Summary
- REGISTERED =
Hash containing all the available languages.
{}
Instance Attribute Summary (collapse)
-
- (Object) collections
A hash of all the language files that have been loaded for a language.
-
- (Object) name
The name of the language.
-
- (TrueClass|FalseClass) rtl
Returns a boolean that indicates whether or not the language reads from right to left.
-
- (Object) title
The title of the language (in that specific language).
Class Method Summary (collapse)
-
+ (Object) add { ... }
Adds a new language.
-
+ (String) current
Returns an instance of Language for the current language.
-
+ (String) html_head
Builds an HTML opening tag with the lang and rtl attributes set for the currently used language.
-
+ (Object) load(lang_name, lang = nil)
Loads the given language file for the currently used language.
-
+ (Hash) to_hash
Returns a hash where the keys are the language codes and the values the titles.
Instance Method Summary (collapse)
-
- (Language) initialize
constructor
Creates a new instance of the class.
-
- (Object) validate
Validates the current instance using Validation.
Methods included from Validation
#validates_filepath, #validates_format, #validates_length, #validates_presence
Constructor Details
- (Language) initialize
Creates a new instance of the class.
335 336 337 338 |
# File 'lib/zen/language.rb', line 335 def initialize @loaded = [] @collections = {} end |
Instance Attribute Details
- (Object) collections
A hash of all the language files that have been loaded for a language. The values are the names of these collections and the values the instances of Translation.
182 183 184 |
# File 'lib/zen/language.rb', line 182 def collections @collections end |
- (Object) name
The name of the language
171 172 173 |
# File 'lib/zen/language.rb', line 171 def name @name end |
- (TrueClass|FalseClass) rtl
Returns a boolean that indicates whether or not the language reads from right to left.
357 358 359 |
# File 'lib/zen/language.rb', line 357 def rtl return @rtl.nil? ? false : @rtl end |
- (Object) title
The title of the language (in that specific language).
177 178 179 |
# File 'lib/zen/language.rb', line 177 def title @title end |
Class Method Details
+ (Object) add { ... }
Adds a new language.
204 205 206 207 208 209 210 211 212 |
# File 'lib/zen/language.rb', line 204 def add lang = new yield(lang) lang.validate REGISTERED[lang.name] = lang end |
+ (String) current
Returns an instance of Zen::Language for the current language.
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/zen/language.rb', line 258 def current if !Ramaze::Current.actions.nil? and !Ramaze::Current.action.nil? # The backend if Ramaze::Current.action.node.request.env['SCRIPT_NAME'] \ =~ /^\/admin.*/ method = :language # Probably the frontend else method = :frontend_language end # Extract the language from the current User object. if Ramaze::Helper.const_defined?(:UserHelper) model = Ramaze::Current.action.node.request \ .env[::Ramaze::Helper::UserHelper::RAMAZE_HELPER_USER] if model.respond_to?(method) lang = model.send(method) end end end # Make sure there always is a language set if !lang begin if method lang = get_setting(method).value else lang = get_setting(:language).value end rescue lang = Zen::Language..language end end return REGISTERED[lang] end |
+ (String) html_head
Builds an HTML opening tag with the lang and rtl attributes set for the currently used language.
318 319 320 321 322 323 324 325 326 327 |
# File 'lib/zen/language.rb', line 318 def html_head curr = Zen::Language.current head = "<html lang=\"#{curr.name}\"" if curr.rtl == true header += ' dir="rtl"' end return head + '>' end |
+ (Object) load(lang_name, lang = nil)
Loads the given language file for the currently used language. If the file has already been loaded this method will not load it again.
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/zen/language.rb', line 226 def load(lang_name, lang = nil) lang_name = lang_name.to_s unless lang_name.is_a?(String) language = REGISTERED[lang.to_s] || current return if language.collections.keys.include?(lang_name) .paths.each do |path| path = File.join(path, language.name, "#{lang_name}.rb") # Load the language if File.exist?(path) require(path) unless language.collections[lang_name].nil? language.collections[lang_name].load return end end end raise( Zen::LanguageError, "No language file could be found for \"#{lang_name}\"" ) end |
+ (Hash) to_hash
Returns a hash where the keys are the language codes and the values the titles.
303 304 305 306 307 308 309 |
# File 'lib/zen/language.rb', line 303 def to_hash hash = {} REGISTERED.each { |lang, obj| hash[lang] = obj.title } return hash end |
Instance Method Details
- (Object) validate
Validates the current instance using Validation.
366 367 368 369 370 371 372 |
# File 'lib/zen/language.rb', line 366 def validate validates_presence([:name, :title]) if REGISTERED.key?(name) raise(Zen::ValidationError, "The language #{name} already exists.") end end |