class Tr8n::Token

Public Class Methods

expression() click to toggle source
# File lib/tr8n/token.rb, line 43
def self.expression
  raise Tr8n::TokenException.new("This method must be implemented in the extending class")
end
new(label, token) click to toggle source
# File lib/tr8n/token.rb, line 55
def initialize(label, token)
  @label = label
  @full_name = token 
end
parse(label) click to toggle source
# File lib/tr8n/token.rb, line 47
def self.parse(label)
  tokens = []
  label.scan(expression).uniq.each do |token_array|
    tokens << self.new(label, token_array.first) 
  end
  tokens
end
register_data_tokens(label) click to toggle source
# File lib/tr8n/token.rb, line 26
def self.register_data_tokens(label)
  tokens = []
  Tr8n::Config.data_token_classes.each do |token_class|
    tokens << token_class.parse(label)
  end

  tokens.flatten
end
register_decoration_tokens(label) click to toggle source
# File lib/tr8n/token.rb, line 35
def self.register_decoration_tokens(label)
  tokens = []
  Tr8n::Config.decoration_token_classes.each do |token_class|
    tokens << token_class.parse(label)
  end
  tokens.flatten
end

Public Instance Methods

allowed_in_translation?() click to toggle source
# File lib/tr8n/token.rb, line 382
def allowed_in_translation?
  true
end
apply_case(object, value, options, language) click to toggle source
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/token.rb, line 397
def apply_case(object, value, options, language)
  return value unless Tr8n::Config.enable_language_cases?
  lcase = language.case_for(case_key)
  return value unless lcase
  lcase.apply(object, value, options)
end
case_key() click to toggle source
# File lib/tr8n/token.rb, line 97
def case_key
  return nil unless declared_name.index('::')

  @case_key ||= begin
    cases = declared_name.scan(/((::[\w]+)+)/).flatten.uniq
    if cases.any?
      cases.last.gsub("::", "")
    else
      nil
    end
  end
end
caseless_name() click to toggle source
# File lib/tr8n/token.rb, line 118
def caseless_name
  @caseless_name ||= begin
    if has_case_key?
      pipeless_name.gsub("::#{case_key}", "")
    else  
      pipeless_name
    end
  end
end
declared_name() click to toggle source
# File lib/tr8n/token.rb, line 68
def declared_name
  @declared_name ||= full_name.gsub(/[{}\[\]]/, '')
end
decoration?() click to toggle source
# File lib/tr8n/token.rb, line 212
def decoration?
  false
end
dependant?() click to toggle source
# File lib/tr8n/token.rb, line 192
def dependant?
  not dependency_rules.empty?
end
dependencies() click to toggle source
# File lib/tr8n/token.rb, line 177
def dependencies
  return nil unless dependant?
  @dependencies ||= language_rules.collect{|rule| rule.dependency}
end
dependency() click to toggle source
# File lib/tr8n/token.rb, line 182
def dependency
  return nil unless dependant?
  @dependency ||= language_rule.dependency
end
dependency_rules() click to toggle source
# File lib/tr8n/token.rb, line 173
def dependency_rules
  @dependency_rules ||= language_rules.select{|rule| rule.transformable?}
end
evaluate_token_method_array(object, method_array, options, language) click to toggle source

gets the value based on various evaluation methods

examples:

tr(“Hello {user}”, “”, {:user => [current_user, current_user.name]}} tr(“Hello {user}”, “”, {:user => [current_user, “{$0} {$1}”, “param1”]}} tr(“Hello {user}”, “”, {:user => [current_user, :name]}} tr(“Hello {user}”, “”, {:user => [current_user, :method_name, “param1”]}} tr(“Hello {user}”, “”, {:user => [current_user, lambda{|user| user.name}]}} tr(“Hello {user}”, “”, {:user => [current_user, lambda{|user, param1| user.name}, “param1”]}}

# File lib/tr8n/token.rb, line 230
def evaluate_token_method_array(object, method_array, options, language)
  # if single object in the array return string value of the object
  if method_array.size == 1
    return sanitize_token_value(object, object.to_s, options, language)
  end  

  # second params identifies the method to be used with the object
  method = method_array.second
  params = method_array[2..-1]
  params_with_object = [object] + params

  # if the second param is a string, substitute all of the numeric params,
  # with the original object and all the following params
  if method.is_a?(String)
    parametrized_value = method.clone
    if parametrized_value.index("{$")
      params_with_object.each_with_index do |val, i|
         parametrized_value.gsub!("{$#{i}}", sanitize_token_value(object, val, options.merge(:skip_decorations => true), language))  
      end
    end
    return sanitize_token_value(object, parametrized_value, options, language)
  end

  # if second param is symbol, invoke the method on the object with the remaining values
  if method.is_a?(Symbol)
    return sanitize_token_value(object, object.send(method, *params), options.merge(:sanitize_values => true), language)
  end

  # if second param is lambda, call lambda with the remaining values
  if method.is_a?(Proc)
    return sanitize_token_value(object, method.call(*params_with_object), options, language)
  end

  raise Tr8n::TokenException.new("Invalid array second token value: #{full_name} in #{original_label}")
end
full_name() click to toggle source
# File lib/tr8n/token.rb, line 64
def full_name
  @full_name
end
has_case_key?() click to toggle source
# File lib/tr8n/token.rb, line 114
def has_case_key?
  not case_key.blank?
end
has_type?() click to toggle source
# File lib/tr8n/token.rb, line 155
def has_type?
  not type.blank?
end
language_rule() click to toggle source

used for transform tokens - be aware that if you have multiple rules on a token - the first one will be selected

# File lib/tr8n/token.rb, line 188
def language_rule
  @language_rule ||= dependency_rules.first
end
language_rules() click to toggle source
# File lib/tr8n/token.rb, line 159
def language_rules
  @language_rules ||= begin
    if has_type? # if token has a type - force that type and nothing else
      rule = Tr8n::Config.language_rule_dependencies[type]
      unless rule
        raise Tr8n::TokenException.new("Unknown dependency type for #{full_name} token")
      end
      [rule]
    else # find all language rules for the suffix
      [] + Tr8n::Config.language_rules_for_suffix(suffix)
    end
  end
end
name() click to toggle source
# File lib/tr8n/token.rb, line 72
def name
  @name ||= declared_name.split(':').first.strip
end
name_for_case(case_key) click to toggle source

used by the translator submit dialog

# File lib/tr8n/token.rb, line 134
def name_for_case(case_key)
  "#{name}::#{case_key}"
end
name_key() click to toggle source
# File lib/tr8n/token.rb, line 89
def name_key
  name.to_sym
end
name_with_case() click to toggle source
# File lib/tr8n/token.rb, line 128
def name_with_case
  return name unless has_case_key?
  "#{name}::#{case_key}"
end
original_label() click to toggle source
# File lib/tr8n/token.rb, line 60
def original_label
  @label
end
permutable_name() click to toggle source
# File lib/tr8n/token.rb, line 76
def permutable_name
  @permutable_name ||= name.split(".").first
end
pipeless_name() click to toggle source
# File lib/tr8n/token.rb, line 93
def pipeless_name
  @pipeless_name ||= declared_name.split('|').first
end
prepare_label_for_suggestion(label, index) click to toggle source

return tokenless form

# File lib/tr8n/token.rb, line 431
def prepare_label_for_suggestion(label, index)
  label.gsub(full_name, "(#{index})")
end
prepare_label_for_translator(label) click to toggle source

return sanitized form

# File lib/tr8n/token.rb, line 426
def prepare_label_for_translator(label)
  label.gsub(full_name, sanitized_name)
end
sanitize_token_value(object, value, options, language) click to toggle source
# File lib/tr8n/token.rb, line 196
def sanitize_token_value(object, value, options, language)
  value = "#{value.to_s}" unless value.is_a?(String)

  unless Tr8n::Config.block_options[:skip_html_escaping]
    if options[:sanitize_values] and not value.html_safe?
      value = ERB::Util.html_escape(value)
    end
  end

  if has_case_key?
    value = apply_case(object, value, options, language)
  end

  value
end
sanitized_name() click to toggle source

used for the UI substitution

# File lib/tr8n/token.rb, line 85
def sanitized_name
  "{#{name}}"
end
sanitized_name_for_case(case_key) click to toggle source

used by the translator submit dialog

# File lib/tr8n/token.rb, line 139
def sanitized_name_for_case(case_key)
  "{#{name_for_case(case_key)}}"
end
substitute(label, values = {}, options = {}, language = Tr8n::Config.current_language) click to toggle source
# File lib/tr8n/token.rb, line 404
def substitute(label, values = {}, options = {}, language = Tr8n::Config.current_language)
  # get the object from the values
  object = values[name_key]

  # see if the token is a default html token
  object = Tr8n::Config.default_data_tokens[name_key] if object.nil?

  if object.nil? and not values.key?(name_key) 
    raise Tr8n::TokenException.new("Missing value for a token: #{full_name}")
  end

  if object.nil? and not Tr8n::Config.allow_nil_token_values?
    raise Tr8n::TokenException.new("Token value is nil for a token: #{full_name}")
  end

  object = object.to_s if object.nil?

  value = token_value(object, options, language)
  label.gsub(full_name, value)
end
suffix() click to toggle source
# File lib/tr8n/token.rb, line 80
def suffix
  @suffix ||= name.split('_').last
end
supports_cases?() click to toggle source
# File lib/tr8n/token.rb, line 110
def supports_cases?
  true
end
to_s() click to toggle source
# File lib/tr8n/token.rb, line 435
def to_s
  full_name
end
token_array_value(token_value, options, language) click to toggle source

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(“{user_list} joined Geni”, “”,

{:user_list => [[user1, user2, user3], 
                  [:name],      # this can be any of the value methods
                  { :expandable => true, 
                    :to_sentence => true, 
                    :limit => 4, 
                    :separator => ',',
                    :translate_items => false,
                    :minimizable => true
                  }
                ]
               ]})

acceptable params: expandable,

to_sentence, 
limit, 
separator, 
translate_items,
minimizable
# File lib/tr8n/token.rb, line 295
def token_array_value(token_value, options, language) 
  objects = token_value.first

  objects = objects.collect do |obj|
    if token_value.second.is_a?(Array)
      evaluate_token_method_array(obj, [obj] + token_value.second, options, language)
    else
      evaluate_token_method_array(obj, token_value, options, language)
    end
  end

  list_options = {
    :translate_items => false,
    :expandable => true,
    :minimizable => true,
    :to_sentence => true,
    :limit => 4,
    :separator => ", "
  }

  if token_value.second.is_a?(Array) and token_value.size == 3
    list_options.merge!(token_value.last) 
  end

  objects = objects.collect{|obj| obj.translate("List element", {}, options)} if list_options[:translate_items]

  # if there is only one element in the array, use it and get out
  return objects.first if objects.size == 1
 
  list_options[:expandable] = false if options[:skip_decorations]

  return objects.join(list_options[:separator]) unless list_options[:to_sentence]

  if objects.size <= list_options[:limit]
    return "#{objects[0..-2].join(list_options[:separator])} #{"and".translate("List elements joiner", {}, options)} #{objects.last}"
  end

  display_ary = objects[0..(list_options[:limit]-1)]
  remaining_ary = objects[list_options[:limit]..-1]
  result = "#{display_ary.join(list_options[:separator])}"

  unless list_options[:expandable]
    result << " " << "and".translate("List elements joiner", {}, options) << " "
    result << "{num} {_others}".translate("List elements joiner", 
              {:num => remaining_ary.size, :_others => "other".pluralize_for(remaining_ary.size)}, options)
    return result
  end             
         
  uniq_id = Tr8n::TranslationKey.generate_key(original_label, objects.join(","))         
  result << "<span id=\"tr8n_other_link_#{uniq_id}\">" << " " << "and".translate("List elements joiner", {}, options) << " "
  result << "<a href='#' onClick=\"Tr8n.Effects.hide('tr8n_other_link_#{uniq_id}'); Tr8n.Effects.show('tr8n_other_elements_#{uniq_id}'); return false;\">"
  result << "{num|| other}".translate("List elements joiner", {:num => remaining_ary.size}, options)
  result << "</a></span>"
  result << "<span id=\"tr8n_other_elements_#{uniq_id}\" style='display:none'>" << list_options[:separator]
  result << "#{remaining_ary[0..-2].join(list_options[:separator])} #{"and".translate("List elements joiner", {}, options)} #{remaining_ary.last}"

  if list_options[:minimizable]
    result << "<a href='#' style='font-size:smaller;white-space:nowrap' onClick=\"Tr8n.Effects.show('tr8n_other_link_#{uniq_id}'); Tr8n.Effects.hide('tr8n_other_elements_#{uniq_id}'); return false;\"> "
    result << "&laquo; less".translate("List elements joiner", {}, options)    
    result << "</a>"
  end

  result << "</span>"
end
token_value(object, options, language) click to toggle source

evaluate all possible methods for the token value and return sanitized result

# File lib/tr8n/token.rb, line 361
def token_value(object, options, language)
  # token is an array
  if object.is_a?(Array)
    # if you provided an array, it better have some values
    if object.empty?
      return raise Tr8n::TokenException.new("Invalid array value for a token: #{full_name}")
    end

    # if the first value of an array is an array handle it here
    if object.first.kind_of?(Enumerable)
      return token_array_value(object, options, language)
    end

    # if the first item in the array is an object, process it
    return evaluate_token_method_array(object.first, object, options, language)
  end

  # simple token
  sanitize_token_value(object, object.to_s, options, language)    
end
type() click to toggle source
# File lib/tr8n/token.rb, line 143
def type
  return nil unless caseless_name.index(':')
  @type ||= begin 
    parts = caseless_name.split(':')
    if parts.size == 1 # provided : without a type
      nil
    else
      parts.last
    end
  end
end