Class ArkanisDevelopment::SimpleLocalization::LangFile
In: lib/lang_file.rb
Parent: Object

The LangFile class is the interface for the Simple Localization plugin to work with the language files. This class takes care of loading a language file and provides a simple way to access its data using the NestedHash class.

What are language files?

The Simple Localization plugin uses language files to store the data needed for a specific language. These files are built using YAML and are therefore easy to read and write.

Methods

Attributes

data  [R] 
lang_code  [R] 
lang_file_dirs  [R] 
ruby_parts  [R] 
yaml_parts  [R] 

Public Class methods

Creates a new LangFile object for the language lang_code which looks for source files in the directories specified in lang_file_dirs.

  LangFile.new :en, 'lang_files'
  LangFile.new :en, ['lang_files', 'plugins/lang_files', 'some_dir/with_even_more_lang_files']

The first example will look for en*.yml language files which are located in the lang_file directory.

The second example will look for en*.yml language files, too. However not only in the lang_files directory but also in the directories plugins/lang_files and some_dir/with_even_more_lang_files. The language files are loaded in the order the directories are specified. So entries of language files in the some_dir/with_even_more_lang_files directory will overwrite any previous entries with the same name. Adding new keys to the language file goes in reverse order. A new key for en.yml will be added to some_dir/with_even_more_lang_files/en.yml.

[Source]

    # File lib/lang_file.rb, line 40
40:       def initialize(lang_code, lang_file_dirs)
41:         @lang_code, @lang_file_dirs = lang_code.to_sym, Array(lang_file_dirs)
42:         @yaml_parts, @ruby_parts = [], []
43:         # Create a new NestedHash but raise an EntryNotFound exception as
44:         # default action (if no matching key is found).
45:         @data = NestedHash.new do raise EntryNotFound end
46:       end

Public Instance methods

Returns a hash with the meta data of this language (language name, author, date, ect.). Entries not present in the language file will default to nil.

[Source]

     # File lib/lang_file.rb, line 91
 91:       def about
 92:         defaults = {
 93:           :language => nil,
 94:           :author => nil,
 95:           :comment => nil,
 96:           :website => nil,
 97:           :email => nil,
 98:           :date => nil
 99:         }
100:         
101:         begin
102:           self.data['about'] ? defaults.update(self.data['about'].symbolize_keys) : defaults
103:         rescue EntryNotFound
104:           defaults
105:         end
106:       end

This method loads the base YAML language file (eg. de.yml) and all other language file parts (eg. de.app.about.yml) extending the language. These parts are sorted after their length (specifity), the shortes first, and then inserted into the language data. At the end the ruby file belonging to the language is loaded (eg. de.rb).

[Source]

    # File lib/lang_file.rb, line 54
54:       def load
55:         @yaml_parts, @ruby_parts = lookup_parts
56:         @data.clear
57:         self.yaml_parts_in_loading_order.each do |yaml_part|
58:           yaml_data = YAML.load_file(yaml_part)
59:           part_sections = File.basename(yaml_part, '.yml').split('.')
60:           part_sections.delete_at 0 # delete the 'en' at the beginning
61:           if part_sections.empty?
62:             @data.merge! yaml_data
63:           else
64:             begin
65:               target_section = @data[*part_sections]
66:               raise EntryNotFound unless target_section.respond_to? :merge!
67:               target_section.merge! yaml_data
68:             rescue EntryNotFound
69:               @data[*part_sections] = yaml_data
70:             end
71:           end
72:         end
73:         
74:         @ruby_parts.each do |ruby_part|
75:           Kernel.load ruby_part
76:         end
77:       end

Reloads the data from the language file and merges it with the existing data in the memory. In case of a conflict the new entries from the language file overwrite the entries in the memory.

[Source]

    # File lib/lang_file.rb, line 82
82:       def reload
83:         old_data = @data.dup
84:         self.load
85:         @data = old_data.merge! @data
86:       end

Protected Instance methods

Just searches for the YAML and Ruby parts. The YAML parts are NOT correctly sorted by this method. The Ruby parts are in proper order.

To sort the YAML parts please use the yaml_parts_in_loading_order or yaml_parts_in_saving_order methods.

[Source]

     # File lib/lang_file.rb, line 115
115:       def lookup_parts
116:         @yaml_parts = ActiveSupport::OrderedHash.new
117:         @ruby_parts = []
118:         
119:         self.lang_file_dirs.each do |lang_file_dir|
120:           yaml_parts_in_this_dir = Dir.glob(File.join(lang_file_dir, "#{self.lang_code}*.yml")).sort
121:           @yaml_parts[lang_file_dir] = yaml_parts_in_this_dir.collect {|part| File.basename(part)}
122:           ruby_part_in_this_dir = File.join(lang_file_dir, "#{self.lang_code}.rb")
123:           @ruby_parts << ruby_part_in_this_dir if File.exists?(ruby_part_in_this_dir)
124:         end
125:         
126:         [@yaml_parts, @ruby_parts]
127:       end

Sorts the specified YAML parts in proper loading order. That means first by directories and then by the specificity of the parts. Specificity is the number of section names contained in the file name of the part. More section names results in a higher specificity.

[Source]

     # File lib/lang_file.rb, line 133
133:       def yaml_parts_in_loading_order
134:         ordered_yaml_parts = []
135:         @yaml_parts.each do |lang_file_dir, parts_in_this_dir|
136:           parts_in_this_dir.sort_by{|part| File.basename(part, '.yml').split('.').size}.each do |part|
137:             ordered_yaml_parts << File.join(lang_file_dir, part)
138:           end
139:         end
140:         ordered_yaml_parts
141:       end

Sorts the YAML parts in proper write order. That means they are orderd first by their specificity and then by the language file directory priority.

[Source]

     # File lib/lang_file.rb, line 146
146:       def yaml_parts_in_saving_order
147:         lang_file_dirs_by_parts = ActiveSupport::OrderedHash.new
148:         @yaml_parts.each do |lang_file_dir, parts_in_this_dir|
149:           parts_in_this_dir.each do |part|
150:             lang_file_dirs_by_parts[part] = (lang_file_dirs_by_parts[part] || []) << lang_file_dir
151:           end
152:         end
153:         
154:         ordered_yaml_parts = []
155:         lang_file_dirs_by_parts.keys.sort_by{|key| key.split('.').size}.reverse.each do |part|
156:           lang_file_dirs_by_parts[part].reverse.each do |lang_file_dir|
157:             ordered_yaml_parts << File.join(lang_file_dir, part)
158:           end
159:         end
160:         
161:         ordered_yaml_parts
162:       end

[Validate]