tml 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +243 -0
  4. data/Rakefile +9 -0
  5. data/lib/tml.rb +56 -0
  6. data/lib/tml/api/client.rb +206 -0
  7. data/lib/tml/api/post_office.rb +71 -0
  8. data/lib/tml/application.rb +254 -0
  9. data/lib/tml/base.rb +116 -0
  10. data/lib/tml/cache.rb +143 -0
  11. data/lib/tml/cache_adapters/file.rb +89 -0
  12. data/lib/tml/cache_adapters/memcache.rb +104 -0
  13. data/lib/tml/cache_adapters/memory.rb +85 -0
  14. data/lib/tml/cache_adapters/redis.rb +108 -0
  15. data/lib/tml/config.rb +410 -0
  16. data/lib/tml/decorators/base.rb +52 -0
  17. data/lib/tml/decorators/default.rb +43 -0
  18. data/lib/tml/decorators/html.rb +102 -0
  19. data/lib/tml/exception.rb +35 -0
  20. data/lib/tml/ext/array.rb +86 -0
  21. data/lib/tml/ext/date.rb +99 -0
  22. data/lib/tml/ext/fixnum.rb +47 -0
  23. data/lib/tml/ext/hash.rb +99 -0
  24. data/lib/tml/ext/string.rb +56 -0
  25. data/lib/tml/ext/time.rb +89 -0
  26. data/lib/tml/generators/cache/base.rb +117 -0
  27. data/lib/tml/generators/cache/file.rb +159 -0
  28. data/lib/tml/language.rb +175 -0
  29. data/lib/tml/language_case.rb +105 -0
  30. data/lib/tml/language_case_rule.rb +76 -0
  31. data/lib/tml/language_context.rb +117 -0
  32. data/lib/tml/language_context_rule.rb +56 -0
  33. data/lib/tml/languages/en.json +1363 -0
  34. data/lib/tml/logger.rb +109 -0
  35. data/lib/tml/rules_engine/evaluator.rb +162 -0
  36. data/lib/tml/rules_engine/parser.rb +65 -0
  37. data/lib/tml/session.rb +199 -0
  38. data/lib/tml/source.rb +106 -0
  39. data/lib/tml/tokenizers/data.rb +96 -0
  40. data/lib/tml/tokenizers/decoration.rb +204 -0
  41. data/lib/tml/tokenizers/dom.rb +346 -0
  42. data/lib/tml/tokens/data.rb +403 -0
  43. data/lib/tml/tokens/method.rb +61 -0
  44. data/lib/tml/tokens/transform.rb +223 -0
  45. data/lib/tml/translation.rb +67 -0
  46. data/lib/tml/translation_key.rb +178 -0
  47. data/lib/tml/translator.rb +47 -0
  48. data/lib/tml/utils.rb +130 -0
  49. data/lib/tml/version.rb +34 -0
  50. metadata +121 -0
data/lib/tml/logger.rb ADDED
@@ -0,0 +1,109 @@
1
+ # encoding: UTF-8
2
+ #--
3
+ # Copyright (c) 2015 Translation Exchange, Inc
4
+ #
5
+ # _______ _ _ _ ______ _
6
+ # |__ __| | | | | (_) | ____| | |
7
+ # | |_ __ __ _ _ __ ___| | __ _| |_ _ ___ _ __ | |__ __ _____| |__ __ _ _ __ __ _ ___
8
+ # | | '__/ _` | '_ \/ __| |/ _` | __| |/ _ \| '_ \| __| \ \/ / __| '_ \ / _` | '_ \ / _` |/ _ \
9
+ # | | | | (_| | | | \__ \ | (_| | |_| | (_) | | | | |____ > < (__| | | | (_| | | | | (_| | __/
10
+ # |_|_| \__,_|_| |_|___/_|\__,_|\__|_|\___/|_| |_|______/_/\_\___|_| |_|\__,_|_| |_|\__, |\___|
11
+ # __/ |
12
+ # |___/
13
+ # Permission is hereby granted, free of charge, to any person obtaining
14
+ # a copy of this software and associated documentation files (the
15
+ # "Software"), to deal in the Software without restriction, including
16
+ # without limitation the rights to use, copy, modify, merge, publish,
17
+ # distribute, sublicense, and/or sell copies of the Software, and to
18
+ # permit persons to whom the Software is furnished to do so, subject to
19
+ # the following conditions:
20
+ #
21
+ # The above copyright notice and this permission notice shall be
22
+ # included in all copies or substantial portions of the Software.
23
+ #
24
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+ #++
32
+
33
+ require 'logger'
34
+
35
+ module Tml
36
+
37
+ def self.logger
38
+ @logger ||= begin
39
+ logfile_path = File.expand_path(Tml.config.logger[:path])
40
+ logfile_dir = logfile_path.split("/")[0..-2].join("/")
41
+ FileUtils.mkdir_p(logfile_dir) unless File.exist?(logfile_dir)
42
+ logfile = File.open(logfile_path, 'a')
43
+ logfile.sync = true
44
+ Tml::Logger.new(logfile)
45
+ end
46
+ end
47
+
48
+ class Logger < ::Logger
49
+
50
+ def format_message(severity, timestamp, progname, msg)
51
+ return "" unless Tml.config.logger[:enabled]
52
+ # TODO: check for severity/level
53
+ "[#{timestamp.strftime("%D %T")}]: #{" " * stack.size}#{msg}\n"
54
+ end
55
+
56
+ def add(severity, message = nil, progname = nil, &block)
57
+ return unless Tml.config.logger[:enabled]
58
+ super
59
+ end
60
+
61
+ def stack
62
+ @stack ||= []
63
+ end
64
+
65
+ def trace_api_call(path, params, opts = {})
66
+ #[:client_secret, :access_token].each do |param|
67
+ # params = params.merge(param => "##filtered##") if params[param]
68
+ #end
69
+ if opts[:method] == :post
70
+ debug("post: [#{path}] #{params.inspect}")
71
+ else
72
+ debug("get: #{path}?#{to_query(params)}")
73
+ end
74
+ stack.push(caller)
75
+ t0 = Time.now
76
+ if block_given?
77
+ ret = yield
78
+ end
79
+ t1 = Time.now
80
+ stack.pop
81
+ debug("call took #{t1 - t0} seconds")
82
+ ret
83
+ end
84
+
85
+ def to_query(hash)
86
+ query = []
87
+ hash.each do |key, value|
88
+ query << "#{key}=#{value}"
89
+ end
90
+ query.join('&')
91
+ end
92
+
93
+ def trace(message)
94
+ debug(message)
95
+ stack.push(caller)
96
+ t0 = Time.now
97
+ if block_given?
98
+ ret = yield
99
+ end
100
+ t1 = Time.now
101
+ stack.pop
102
+ debug("execution took #{t1 - t0} seconds")
103
+ ret
104
+ end
105
+
106
+ end
107
+
108
+ end
109
+
@@ -0,0 +1,162 @@
1
+ # encoding: UTF-8
2
+ #--
3
+ # Copyright (c) 2015 Translation Exchange, Inc
4
+ #
5
+ # _______ _ _ _ ______ _
6
+ # |__ __| | | | | (_) | ____| | |
7
+ # | |_ __ __ _ _ __ ___| | __ _| |_ _ ___ _ __ | |__ __ _____| |__ __ _ _ __ __ _ ___
8
+ # | | '__/ _` | '_ \/ __| |/ _` | __| |/ _ \| '_ \| __| \ \/ / __| '_ \ / _` | '_ \ / _` |/ _ \
9
+ # | | | | (_| | | | \__ \ | (_| | |_| | (_) | | | | |____ > < (__| | | | (_| | | | | (_| | __/
10
+ # |_|_| \__,_|_| |_|___/_|\__,_|\__|_|\___/|_| |_|______/_/\_\___|_| |_|\__,_|_| |_|\__, |\___|
11
+ # __/ |
12
+ # |___/
13
+ # Permission is hereby granted, free of charge, to any person obtaining
14
+ # a copy of this software and associated documentation files (the
15
+ # "Software"), to deal in the Software without restriction, including
16
+ # without limitation the rights to use, copy, modify, merge, publish,
17
+ # distribute, sublicense, and/or sell copies of the Software, and to
18
+ # permit persons to whom the Software is furnished to do so, subject to
19
+ # the following conditions:
20
+ #
21
+ # The above copyright notice and this permission notice shall be
22
+ # included in all copies or substantial portions of the Software.
23
+ #
24
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+ #++
32
+
33
+ module Tml
34
+ module RulesEngine
35
+
36
+ class Evaluator
37
+ attr_reader :env, :vars
38
+
39
+ def initialize
40
+ @vars = {}
41
+ @env = {
42
+ # McCarthy's Elementary S-functions and Predicates
43
+ 'label' => lambda { |l, r| @vars[l] = r },
44
+ 'quote' => lambda { |expr| expr },
45
+ 'car' => lambda { |list| list[1] },
46
+ 'cdr' => lambda { |list| list.drop(1) },
47
+ 'cons' => lambda { |e, cell| [e] + cell },
48
+ 'eq' => lambda { |l, r| l == r },
49
+ 'atom' => lambda { |expr| [Symbol, String, Fixnum, Float].include?(expr.class) },
50
+ 'cond' => lambda { |c, t, f| evaluate(c) ? evaluate(t) : evaluate(f) },
51
+
52
+ # Tml Extensions
53
+ '=' => lambda { |l, r| l == r }, # ['=', 1, 2]
54
+ '!=' => lambda { |l, r| l != r }, # ['!=', 1, 2]
55
+ '<' => lambda { |l, r| l < r }, # ['<', 1, 2]
56
+ '>' => lambda { |l, r| l > r }, # ['>', 1, 2]
57
+ '+' => lambda { |l, r| l + r }, # ['+', 1, 2]
58
+ '-' => lambda { |l, r| l - r }, # ['-', 1, 2]
59
+ '*' => lambda { |l, r| l * r }, # ['*', 1, 2]
60
+ '%' => lambda { |l, r| l % r }, # ['%', 14, 10]
61
+ 'mod' => lambda { |l, r| l % r }, # ['mod', '@n', 10]
62
+ '/' => lambda { |l, r| (l * 1.0) / r }, # ['/', 1, 2]
63
+ '!' => lambda { |expr| not expr }, # ['!', ['true']]
64
+ 'not' => lambda { |val| not val }, # ['not', ['true']]
65
+ '&&' => lambda { |*expr| expr.all?{|e| evaluate(e)} }, # ['&&', [], [], ...]
66
+ 'and' => lambda { |*expr| expr.all?{|e| evaluate(e)} }, # ['and', [], [], ...]
67
+ '||' => lambda { |*expr| expr.any?{|e| evaluate(e)} }, # ['||', [], [], ...]
68
+ 'or' => lambda { |*expr| expr.any?{|e| evaluate(e)} }, # ['or', [], [], ...]
69
+ 'if' => lambda { |c, t, f| evaluate(c) ? evaluate(t) : evaluate(f) }, # ['if', 'cond', 'true', 'false']
70
+ 'let' => lambda { |l, r| @vars[l] = r }, # ['let', 'n', 5]
71
+ 'true' => lambda { true }, # ['true']
72
+ 'false' => lambda { false }, # ['false']
73
+
74
+ 'date' => lambda { |date| Date.strptime(date, '%Y-%m-%d') }, # ['date', '2010-01-01']
75
+ 'today' => lambda { Time.now.to_date }, # ['today']
76
+ 'time' => lambda { |expr| Time.strptime(expr, '%Y-%m-%d %H:%M:%S') }, # ['time', '2010-01-01 10:10:05']
77
+ 'now' => lambda { Time.now }, # ['now']
78
+
79
+ 'append' => lambda { |l, r| r.to_s + l.to_s }, # ['append', 'world', 'hello ']
80
+ 'prepend' => lambda { |l, r| l.to_s + r.to_s }, # ['prepend', 'hello ', 'world']
81
+ 'match' => lambda { |search, subject| # ['match', /a/, 'abc']
82
+ search = regexp_from_string(search)
83
+ not search.match(subject).nil?
84
+ },
85
+ 'in' => lambda { |values, search| # ['in', '1,2,3,5..10,20..24', '@n']
86
+ search = search.to_s.strip
87
+ values.split(',').each do |e|
88
+ if e.index('..')
89
+ bounds = e.strip.split('..')
90
+ return true if (bounds.first.strip..bounds.last.strip).include?(search)
91
+ end
92
+ return true if e.strip == search
93
+ end
94
+ false
95
+ },
96
+ 'within' => lambda { |values, search| # ['within', '0..3', '@n']
97
+ bounds = values.split('..').map{|d| Integer(d)}
98
+ (bounds.first..bounds.last).include?(search)
99
+ },
100
+ 'replace' => lambda { |search, replace, subject| # ['replace', '/^a/', 'v', 'abc']
101
+ # handle regular expression
102
+ if /\/i$/.match(search)
103
+ replace = replace.gsub(/\$(\d+)/, '\\\\\1') # for compatibility with Perl notation
104
+ end
105
+ search = regexp_from_string(search)
106
+ subject.gsub(search, replace)
107
+ },
108
+ 'count' => lambda { |list| # ['count', '@genders']
109
+ (list.is_a?(String) ? vars[list] : list).count
110
+ },
111
+ 'all' => lambda { |list, value| # ['all', '@genders', 'male']
112
+ list = (list.is_a?(String) ? vars[list] : list)
113
+ list.is_a?(Array) ? list.all?{|e| e == value} : false
114
+ },
115
+ 'any' => lambda { |list, value| # ['any', '@genders', 'female']
116
+ list = (list.is_a?(String) ? vars[list] : list)
117
+ list.is_a?(Array) ? list.any?{|e| e == value} : false
118
+ },
119
+ }
120
+ end
121
+
122
+ def regexp_from_string(str)
123
+ return Regexp.new(/#{str}/) unless /^\//.match(str)
124
+
125
+ str = str.gsub(/^\//, '')
126
+
127
+ if /\/i$/.match(str)
128
+ str = str.gsub(/\/i$/, '')
129
+ return Regexp.new(/#{str}/i)
130
+ end
131
+
132
+ str = str.gsub(/\/$/, '')
133
+ Regexp.new(/#{str}/)
134
+ end
135
+
136
+ def reset!
137
+ @vars = {}
138
+ end
139
+
140
+ def apply(fn, args)
141
+ raise "undefined symbols #{fn}" unless @env.keys.include?(fn)
142
+ @env[fn].call(*args)
143
+ end
144
+
145
+ def evaluate(expr)
146
+ if @env['atom'].call(expr)
147
+ return @vars[expr] if expr.is_a?(String) and @vars[expr]
148
+ return expr
149
+ end
150
+
151
+ fn = expr[0]
152
+ args = expr.drop(1)
153
+
154
+ unless %w(quote car cdr cond if && || and or true false let count all any).member?(fn)
155
+ args = args.map { |a| self.evaluate(a) }
156
+ end
157
+ apply(fn, args)
158
+ end
159
+ end
160
+
161
+ end
162
+ end
@@ -0,0 +1,65 @@
1
+ # encoding: UTF-8
2
+ #--
3
+ # Copyright (c) 2015 Translation Exchange, Inc
4
+ #
5
+ # _______ _ _ _ ______ _
6
+ # |__ __| | | | | (_) | ____| | |
7
+ # | |_ __ __ _ _ __ ___| | __ _| |_ _ ___ _ __ | |__ __ _____| |__ __ _ _ __ __ _ ___
8
+ # | | '__/ _` | '_ \/ __| |/ _` | __| |/ _ \| '_ \| __| \ \/ / __| '_ \ / _` | '_ \ / _` |/ _ \
9
+ # | | | | (_| | | | \__ \ | (_| | |_| | (_) | | | | |____ > < (__| | | | (_| | | | | (_| | __/
10
+ # |_|_| \__,_|_| |_|___/_|\__,_|\__|_|\___/|_| |_|______/_/\_\___|_| |_|\__,_|_| |_|\__, |\___|
11
+ # __/ |
12
+ # |___/
13
+ # Permission is hereby granted, free of charge, to any person obtaining
14
+ # a copy of this software and associated documentation files (the
15
+ # "Software"), to deal in the Software without restriction, including
16
+ # without limitation the rights to use, copy, modify, merge, publish,
17
+ # distribute, sublicense, and/or sell copies of the Software, and to
18
+ # permit persons to whom the Software is furnished to do so, subject to
19
+ # the following conditions:
20
+ #
21
+ # The above copyright notice and this permission notice shall be
22
+ # included in all copies or substantial portions of the Software.
23
+ #
24
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+ #++
32
+
33
+ module Tml
34
+ module RulesEngine
35
+
36
+ class Parser
37
+ attr_reader :tokens, :expression
38
+
39
+ def initialize(expression)
40
+ @expression = expression
41
+ if expression =~ /^\(/
42
+ @tokens = expression.scan(/[()]|\w+|@\w+|[\+\-\!\|\=>&<\*\/%]+|".*?"|'.*?'/)
43
+ end
44
+ end
45
+
46
+ def parse
47
+ return @expression unless tokens
48
+ token = tokens.shift
49
+ return nil if token.nil?
50
+ return parse_list if (token) == '('
51
+ return token[1..-2].to_s if token =~ /^['"].*/
52
+ return token.to_i if token =~ /\d+/
53
+ token.to_s
54
+ end
55
+
56
+ def parse_list
57
+ list = []
58
+ list << parse until tokens.empty? or tokens.first == ')'
59
+ tokens.shift
60
+ list
61
+ end
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,199 @@
1
+ # encoding: UTF-8
2
+ #--
3
+ # Copyright (c) 2015 Translation Exchange, Inc
4
+ #
5
+ # _______ _ _ _ ______ _
6
+ # |__ __| | | | | (_) | ____| | |
7
+ # | |_ __ __ _ _ __ ___| | __ _| |_ _ ___ _ __ | |__ __ _____| |__ __ _ _ __ __ _ ___
8
+ # | | '__/ _` | '_ \/ __| |/ _` | __| |/ _ \| '_ \| __| \ \/ / __| '_ \ / _` | '_ \ / _` |/ _ \
9
+ # | | | | (_| | | | \__ \ | (_| | |_| | (_) | | | | |____ > < (__| | | | (_| | | | | (_| | __/
10
+ # |_|_| \__,_|_| |_|___/_|\__,_|\__|_|\___/|_| |_|______/_/\_\___|_| |_|\__,_|_| |_|\__, |\___|
11
+ # __/ |
12
+ # |___/
13
+ # Permission is hereby granted, free of charge, to any person obtaining
14
+ # a copy of this software and associated documentation files (the
15
+ # "Software"), to deal in the Software without restriction, including
16
+ # without limitation the rights to use, copy, modify, merge, publish,
17
+ # distribute, sublicense, and/or sell copies of the Software, and to
18
+ # permit persons to whom the Software is furnished to do so, subject to
19
+ # the following conditions:
20
+ #
21
+ # The above copyright notice and this permission notice shall be
22
+ # included in all copies or substantial portions of the Software.
23
+ #
24
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+ #++
32
+
33
+ module Tml
34
+
35
+ def self.session
36
+ Thread.current[:session] ||= Tml::Session.new
37
+ end
38
+
39
+ class Session
40
+ # Session Attributes - Move to Session
41
+ attr_accessor :application, :current_user, :current_locale, :current_language, :current_translator,
42
+ :current_source, :current_component, :block_options, :cookie_params, :access_token, :tools_enabled
43
+
44
+ def self.access_token
45
+ @access_token
46
+ end
47
+
48
+ def self.access_token=(token)
49
+ @access_token = token
50
+ end
51
+
52
+ def init(opts = {})
53
+ return unless Tml.config.enabled? and Tml.config.application
54
+
55
+ key = opts[:key] || Tml.config.application[:key]
56
+ secret = opts[:secret] || Tml.config.application[:secret]
57
+ host = opts[:host] || Tml.config.application[:host]
58
+
59
+ Tml::Session.access_token ||= begin
60
+ self.access_token = opts[:token] || Tml.config.application[:token]
61
+ self.access_token ||= opts[:access_token] || Tml.config.application[:access_token]
62
+ end
63
+
64
+ Tml.cache.reset_version
65
+
66
+ self.application = Tml.memory.fetch(Tml::Application.cache_key) do
67
+ Tml::Application.new(:host => host, :key => key, :secret => secret, :access_token => Tml::Session.access_token).fetch
68
+ end
69
+
70
+ if Tml.cache.read_only?
71
+ self.class.access_token = self.application.access_token
72
+ end
73
+
74
+ # Tml.logger.info(self.cookie_params.inspect)
75
+
76
+ self.cookie_params = begin
77
+ cookie_name = "trex_#{self.application.key}"
78
+ if opts[:cookies] and opts[:cookies][cookie_name]
79
+ begin
80
+ HashWithIndifferentAccess.new(Tml::Utils.decode_and_verify_params(opts[:cookies][cookie_name], secret))
81
+ rescue Exception => ex
82
+ Tml.logger.error("Failed to parse tml cookie: #{ex.message}")
83
+ {}
84
+ end
85
+ else
86
+ {}
87
+ end
88
+ end
89
+
90
+ self.tools_enabled = opts[:tools_enabled]
91
+ self.current_user = opts[:user]
92
+ self.current_source = opts[:source] || '/tml/core'
93
+ self.current_component = opts[:component]
94
+ self.current_locale = opts[:locale] || self.cookie_params[:locale] || Tml.config.default_locale
95
+
96
+ if self.cookie_params['translator']
97
+ self.current_translator = Tml::Translator.new(self.cookie_params['translator'])
98
+ end
99
+
100
+ # if inline mode don't use any app cache
101
+ if inline_mode?
102
+ self.application = self.application.dup
103
+ self.application.reset_translation_cache
104
+ end
105
+
106
+ if self.current_translator
107
+ self.current_translator.application = self.application
108
+ end
109
+
110
+ self.current_language = self.application.language(self.current_locale)
111
+ end
112
+
113
+ def tools_enabled?
114
+ self.tools_enabled
115
+ end
116
+
117
+ def reset
118
+ self.application= nil
119
+ self.current_user= nil
120
+ self.current_language= nil
121
+ self.current_translator= nil
122
+ self.current_source= nil
123
+ self.current_component= nil
124
+ self.tools_enabled= nil
125
+ self.block_options= nil
126
+ end
127
+
128
+ def current_language
129
+ @current_language ||= Tml.config.default_language
130
+ end
131
+
132
+ def application
133
+ @application ||= Tml::Application.new(:host => Tml::Api::Client::API_HOST)
134
+ end
135
+
136
+ def source_language
137
+ arr = @block_options || []
138
+ arr.reverse.each do |opts|
139
+ return application.language(opts[:locale]) unless opts[:locale].blank?
140
+ end
141
+ application.language
142
+ end
143
+
144
+ def target_language
145
+ arr = @block_options || []
146
+ arr.reverse.each do |opts|
147
+ return application.language(opts[:target_locale]) unless opts[:target_locale].nil?
148
+ end
149
+ current_language
150
+ end
151
+
152
+ def inline_mode?
153
+ current_translator and current_translator.inline?
154
+ end
155
+
156
+ #########################################################
157
+ ## Block Options
158
+ #########################################################
159
+
160
+ def push_block_options(opts)
161
+ (@block_options ||= []).push(opts)
162
+ end
163
+
164
+ def pop_block_options
165
+ return unless @block_options
166
+ @block_options.pop
167
+ end
168
+
169
+ def block_options
170
+ (@block_options ||= []).last || {}
171
+ end
172
+
173
+ def with_block_options(opts)
174
+ push_block_options(opts)
175
+ if block_given?
176
+ ret = yield
177
+ end
178
+ pop_block_options
179
+ ret
180
+ end
181
+
182
+ def current_source_from_block_options
183
+ arr = @block_options || []
184
+ arr.reverse.each do |opts|
185
+ return application.source_by_key(opts[:source]) unless opts[:source].blank?
186
+ end
187
+ nil
188
+ end
189
+
190
+ def current_component_from_block_options
191
+ arr = @block_options || []
192
+ arr.reverse.each do |opts|
193
+ return application.component_by_key(opts[:component]) unless opts[:component].blank?
194
+ end
195
+ Tml.config.current_component
196
+ end
197
+
198
+ end
199
+ end