class Tr8n::Tokens::Data
Attributes
Public Class Methods
# File lib/tr8n/tokens/data.rb, line 39 def self.expression /(\{[^_:][\w]*(:[\w]+)*(::[\w]+)*\})/ end
# File lib/tr8n/tokens/data.rb, line 51 def initialize(label, token) @label = label @full_name = token parse_elements end
# File lib/tr8n/tokens/data.rb, line 43 def self.parse(label, opts = {}) tokens = [] label.scan(expression).uniq.each do |token_array| tokens << self.new(label, token_array.first) end tokens end
returns token object from tokens param
# File lib/tr8n/tokens/data.rb, line 104 def self.token_object(token_values, token_name) return nil if token_values.nil? token_object = Tr8n::Utils.hash_value(token_values, token_name) return token_object.first if token_object.is_a?(Array) if token_object.is_a?(Hash) object = Tr8n::Utils.hash_value(token_object, :object) return object if object end token_object end
Public Instance Methods
- chooses the appropriate case for the token value. case is identified with
-
examples:
tr(“Hello {user::nom}”, “”, :user => current_user) tr(“{actor} gave {target::dat} a present”, “”, :actor => user1, :target => user2) tr(“This is {user::pos} toy”, “”, :user => current_user)
# File lib/tr8n/tokens/data.rb, line 359 def apply_case(key, value, object, language, options) lcase = language.case_by_keyword(key) return value unless lcase lcase.apply(value, object, options) end
# File lib/tr8n/tokens/data.rb, line 365 def apply_language_cases(value, object, language, options) case_keys.each do |key| value = apply_case(key, value, object, language, options) end value end
# File lib/tr8n/tokens/data.rb, line 84 def context_for_language(language) if context_keys.any? language.context_by_keyword(context_keys.first) else language.context_by_token_name(short_name) end end
Utility method for errors
# File lib/tr8n/tokens/data.rb, line 93 def error(msg, return_token = true) Tr8n.logger.error(msg) return_token ? full_name : label end
# File lib/tr8n/tokens/data.rb, line 74 def key short_name.to_sym end
# File lib/tr8n/tokens/data.rb, line 344 def language_cases_enabled? Tr8n.session.application and Tr8n.session.application.feature_enabled?(:language_cases) end
# File lib/tr8n/tokens/data.rb, line 66 def name(opts = {}) val = short_name val = "#{val}:#{context_keys.join(':')}" if opts[:context_keys] and context_keys.any? val = "#{val}::#{case_keys.join('::')}" if opts[:case_keys] and case_keys.any? val = "{#{val}}" if opts[:parens] val end
used by the translator submit dialog
# File lib/tr8n/tokens/data.rb, line 79 def name_for_case_keys(keys) keys = [keys] unless keys.is_a?(Array) "#{name}::#{keys.join('::')}" end
# File lib/tr8n/tokens/data.rb, line 57 def parse_elements name_without_parens = @full_name[1..-2] name_without_case_keys = name_without_parens.split('::').first.strip @short_name = name_without_parens.split(':').first.strip @case_keys = name_without_parens.scan(/(::\w+)/).flatten.uniq.collect{|c| c.gsub('::', '')} @context_keys = name_without_case_keys.scan(/(:\w+)/).flatten.uniq.collect{|c| c.gsub(':', '')} end
# File lib/tr8n/tokens/data.rb, line 331 def sanitize(value, object, language, options) value = value.to_s unless Tr8n.session.block_options[:skip_html_escaping] if options[:safe] == false value = ERB::Util.html_escape(value) end end return value unless language_cases_enabled? apply_language_cases(value, object, language, options) end
# File lib/tr8n/tokens/data.rb, line 394 def sanitized_name name(:parens => true) end
# File lib/tr8n/tokens/data.rb, line 373 def substitute(label, context, language, options = {}) # get the object from the values object = Tr8n::Utils.hash_value(context, key) # see if the token is a default html token object = Tr8n.config.default_token_value(key) if object.nil? if object.nil? and not context.key?(key) return error("Missing value for #{full_name} in #{label}", false) end if object.nil? and not Tr8n::Config.allow_nil_token_values? return error("Token value is nil for #{full_name} in #{label}", false) end return label.gsub(full_name, "") if object.nil? value = token_value(object, language, options) label.gsub(full_name, value) end
# File lib/tr8n/tokens/data.rb, line 398 def to_s full_name end
evaluate all possible methods for the token value and return sanitized result
# File lib/tr8n/tokens/data.rb, line 325 def token_value(object, language, options = {}) return token_value_from_array_param(object, language, options) if object.is_a?(Array) return token_value_from_hash_param(object, language, options) if object.is_a?(Hash) sanitize(object, object, language, options) end
gets the value based on various evaluation methods
examples:
tr(“Hello {user}”, {:user => [current_user, current_user.name]}} tr(“Hello {user}”, {:user => [current_user, :name]}}
tr(“Hello {user}”, {:user => [{:name => “Michael”, :gender => :male}, current_user.name]}} tr(“Hello {user}”, {:user => [{:name => “Michael”, :gender => :male}, :name]}}
# File lib/tr8n/tokens/data.rb, line 252 def token_value_from_array_param(array, language, options) # if you provided an array, it better have some values if array.size < 2 return error("Invalid value for array token #{full_name} in #{label}") end # if the first value of an array is an array handle it here if array[0].is_a?(Array) return token_values_from_array(array, language, options) end if array[1].is_a?(String) return sanitize(array[1], array[0], language, options.merge(:safe => true)) end if array[0].is_a?(Hash) if array[1].is_a?(Symbol) return sanitize(Tr8n::Utils.hash_value(array[0], array[1]), array[0], language, options.merge(:safe => false)) end return error("Invalid value for array token #{full_name} in #{label}") end # if second param is symbol, invoke the method on the object with the remaining values if array[1].is_a?(Symbol) return sanitize(array[0].send(array[1]), array[0], language, options.merge(:safe => false)) end error("Invalid value for array token #{full_name} in #{label}") end
examples:
tr(“Hello {user}”, {:user => {:value => “Michael”, :gender => :male}}}
tr(“Hello {user}”, {:user => {:object => {:gender => :male}, :value => “Michael”}}} tr(“Hello {user}”, {:user => {:object => {:name => “Michael”, :gender => :male}, :property => :name}}} tr(“Hello {user}”, {:user => {:object => {:name => “Michael”, :gender => :male}, :attribute => :name}}}
tr(“Hello {user}”, {:user => {:object => user, :value => “Michael”}}} tr(“Hello {user}”, {:user => {:object => user, :property => :name}}} tr(“Hello {user}”, {:user => {:object => user, :attribute => :name}}}
# File lib/tr8n/tokens/data.rb, line 299 def token_value_from_hash_param(hash, language, options) value = Tr8n::Utils.hash_value(hash, :value) object = Tr8n::Utils.hash_value(hash, :object) unless value.nil? return sanitize(value, object || hash, language, options.merge(:safe => true)) end if object.nil? return error("Missing value for hash token #{full_name} in #{label}") end attr = Tr8n::Utils.hash_value(hash, :attribute) || Tr8n::Utils.hash_value(hash, :property) if object.is_a?(Hash) unless attr.nil? return sanitize(Tr8n::Utils.hash_value(object, attr), object, language, options.merge(:safe => false)) end return error("Missing value for hash token #{full_name} in #{label}") end sanitize(object.send(attr), object, language, options.merge(:safe => false)) end
tr(“Hello {user_list}!”, “”, {:user_list => [[user1, user2, user3], :name]}}
first element is an array, the rest of the elements are similar to the regular tokens lambda, symbol, string, with parameters that follow
if you want to pass options, then make the second parameter an array as well
tr(“{users} joined the site”, {:users => [[user1, user2, user3], :name]})
tr(“{users} joined the site”, {:users => [[user1, user2, user3], lambda{|user| user.name}]})
tr(“{users} joined the site”, {:users => [[user1, user2, user3], {:attribute => :name})
tr(“{users} joined the site”, {:users => [[user1, user2, user3], {:attribute => :name, :value => “<strong>{$0}</strong>”})
tr(“{users} joined the site”, {:users => [[user1, user2, user3], “<strong>{$0}</strong>”)
tr(“{users} joined the site”, {:users => [[user1, user2, user3], :name, {
:limit => 4, :separator => ', ', :joiner => 'and', :remainder => lambda{|elements| tr("#{count||other}", :count => elements.size)}, :expandable => true, :collapsable => true
})
# File lib/tr8n/tokens/data.rb, line 145 def token_values_from_array(params, language, options) list_options = { :description => "List joiner", :limit => 4, :separator => ", ", :joiner => 'and', :less => '{laquo} less', :expandable => true, :collapsable => true } objects = params[0] method = params[1] list_options.merge!(params[2]) if params.size > 2 list_options[:expandable] = false if options[:skip_decorations] values = objects.collect do |obj| if method.is_a?(String) method.gsub("{$0}", sanitize(obj.to_s, obj, language, options.merge(:safe => false))) elsif method.is_a?(Symbol) if obj.is_a?(Hash) value = Tr8n::Utils.hash_value(obj, method) else value = obj.send(method) end sanitize(value, obj, language, options.merge(:safe => false)) elsif method.is_a?(Hash) attr = Tr8n::Utils.hash_value(method, :attribute) || Tr8n::Utils.hash_value(method, :property) if obj.is_a?(Hash) value = Tr8n::Utils.hash_value(obj, attr) else value = obj.send(method) end hash_value = Tr8n::Utils.hash_value(method, :value) if hash_value hash_value.gsub("{$0}", sanitize(value, obj, language, options.merge(:safe => false))) else sanitize(value, obj, language, options.merge(:safe => false)) end elsif method.is_a?(Proc) sanitize(method.call(obj), obj, language, options.merge(:safe => true)) end end return values.first if objects.size == 1 return values.join(list_options[:separator]) if list_options[:joiner].nil? || list_options[:joiner] == "" joiner = language.translate(list_options[:joiner], list_options[:description], {}, options) if values.size <= list_options[:limit] return "#{values[0..-2].join(list_options[:separator])} #{joiner} #{values.last}" end display_ary = values[0..(list_options[:limit]-1)] remaining_ary = values[list_options[:limit]..-1] result = "#{display_ary.join(list_options[:separator])}" unless list_options[:expandable] result << " " << joiner << " " if list_options[:remainder] and list_options[:remainder].is_a?(Proc) result << list_options[:remainder].call(remaining_ary) else result << language.translate("{count||other}", list_options[:description], {:count => remaining_ary.size}, options) end return result end uniq_id = Tr8n::TranslationKey.generate_key(label, values.join(",")) result << "<span id=\"tr8n_other_link_#{uniq_id}\"> #{joiner} " result << "<a href='#' onClick=\"Tr8n.Utils.Effects.hide('tr8n_other_link_#{uniq_id}'); Tr8n.Utils.Effects.show('tr8n_other_elements_#{uniq_id}'); return false;\">" if list_options[:remainder] and list_options[:remainder].is_a?(Proc) result << list_options[:remainder].call(remaining_ary) else result << language.translate("{count||other}", list_options[:description], {:count => remaining_ary.size}, options) end result << "</a></span>" result << "<span id=\"tr8n_other_elements_#{uniq_id}\" style='display:none'>" result << list_options[:separator] << " " result << remaining_ary[0..-2].join(list_options[:separator]) result << " #{joiner} " result << remaining_ary.last if list_options[:collapsable] result << "<a href='#' style='font-size:smaller;white-space:nowrap' onClick=\"Tr8n.Utils.Effects.show('tr8n_other_link_#{uniq_id}'); Tr8n.Utils.Effects.hide('tr8n_other_elements_#{uniq_id}'); return false;\"> " result << language.translate(list_options[:less], list_options[:description], {}, options) result << "</a>" end result << "</span>" end