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.
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.
data | [R] | |
lang_code | [R] | |
lang_file_dirs | [R] | |
ruby_parts | [R] | |
yaml_parts | [R] |
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.
# 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
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.
# 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).
# 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.
# 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
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.
# 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.
# 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.
# 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