tml 4.3.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,89 @@
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
+ class Tml::CacheAdapters::File < Tml::Cache
34
+
35
+ def self.cache_path
36
+ "#{Tml.config.cache[:path]}/#{Tml.config.cache[:version]}"
37
+ end
38
+
39
+ def self.file_path(key)
40
+ File.join(cache_path, "#{key}.json")
41
+ end
42
+
43
+ def cache_name
44
+ 'file'
45
+ end
46
+
47
+ def segmented?
48
+ return true if Tml.config.cache[:segmented].nil?
49
+ Tml.config.cache[:segmented]
50
+ end
51
+
52
+ def fetch(key, opts = {})
53
+ info("Fetching key: #{key}")
54
+
55
+ path = self.class.file_path(key)
56
+
57
+ if File.exists?(path)
58
+ info("Cache hit: #{key}")
59
+ return JSON.parse(File.read(path))
60
+ end
61
+
62
+ info("Cache miss: #{key}")
63
+
64
+ return nil unless block_given?
65
+
66
+ yield
67
+ end
68
+
69
+ def store(key, data, opts = {})
70
+ warn('This is a readonly cache')
71
+ end
72
+
73
+ def delete(key, opts = {})
74
+ warn('This is a readonly cache')
75
+ end
76
+
77
+ def exist?(key, opts = {})
78
+ File.exists?(self.class.file_path(key))
79
+ end
80
+
81
+ def clear(opts = {})
82
+ warn('This is a readonly cache')
83
+ end
84
+
85
+ def read_only?
86
+ true
87
+ end
88
+
89
+ end
@@ -0,0 +1,104 @@
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 'dalli' if defined?(Dalli)
34
+
35
+ class Tml::CacheAdapters::Memcache < Tml::Cache
36
+
37
+ def initialize
38
+ options = { :namespace => Tml.config.cache[:namespace] || 'tml', :compress => Tml.config.cache[:compress].nil? ? true : Tml.config.cache[:compress]}
39
+ @cache = Dalli::Client.new(Tml.config.cache[:host], options)
40
+ end
41
+
42
+ def cache_name
43
+ 'memcache'
44
+ end
45
+
46
+ def read_only?
47
+ false
48
+ end
49
+
50
+ def fetch(key, opts = {})
51
+ data = @cache.get(versioned_key(key, opts))
52
+ if data
53
+ info("Cache hit: #{key}")
54
+ return data
55
+ end
56
+
57
+ info("Cache miss: #{key}")
58
+
59
+ return nil unless block_given?
60
+
61
+ data = yield
62
+
63
+ store(key, data)
64
+
65
+ data
66
+ rescue Exception => ex
67
+ warn("Failed to retrieve data: #{key}")
68
+ return nil unless block_given?
69
+ yield
70
+ end
71
+
72
+ def store(key, data, opts = {})
73
+ info("Cache store: #{key}")
74
+ ttl = opts[:ttl] || Tml.config.cache[:timeout]
75
+ @cache.set(versioned_key(key, opts), data, ttl)
76
+ data
77
+ rescue Exception => ex
78
+ warn("Failed to store data: #{key}")
79
+ data
80
+ end
81
+
82
+ def delete(key, opts = {})
83
+ info("Cache delete: #{key}")
84
+ @cache.delete(versioned_key(key, opts))
85
+ key
86
+ rescue Exception => ex
87
+ warn("Failed to delete data: #{key}")
88
+ key
89
+ end
90
+
91
+ def exist?(key, opts = {})
92
+ data = @cache.get(versioned_key(key, opts))
93
+ not data.nil?
94
+ rescue Exception => ex
95
+ warn("Failed to check if key exists: #{key}")
96
+ false
97
+ end
98
+
99
+ def clear(opts = {})
100
+ info("Cache clear")
101
+ rescue Exception => ex
102
+ warn("Failed to clear cache: #{key}")
103
+ end
104
+ end
@@ -0,0 +1,85 @@
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
+ class Tml::CacheAdapters::Memory < Tml::Cache
34
+
35
+ def self.cache
36
+ @cache ||= {}
37
+ end
38
+
39
+ def self.clear_cache
40
+ @cache = {}
41
+ end
42
+
43
+ def cache_name
44
+ 'memory'
45
+ end
46
+
47
+ def fetch(key, opts = {})
48
+ return yield if Tml.session.inline_mode?
49
+ return yield unless Tml.cache.read_only?
50
+
51
+ data = self.class.cache[key]
52
+
53
+ if data
54
+ info("Cache hit: #{key}")
55
+ return data
56
+ end
57
+
58
+ info("Cache miss: #{key}")
59
+
60
+ return nil unless block_given?
61
+
62
+ data = yield
63
+
64
+ store(key, data)
65
+
66
+ data
67
+ end
68
+
69
+ def store(key, data, opts = {})
70
+ self.class.cache[key] = data
71
+ end
72
+
73
+ def delete(key, opts = {})
74
+ self.class.cache[key] = nil
75
+ end
76
+
77
+ def exist?(key, opts = {})
78
+ not self.class.cache[key].nil?
79
+ end
80
+
81
+ def clear(opts = {})
82
+ self.class.clear_cache
83
+ end
84
+
85
+ end
@@ -0,0 +1,108 @@
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
+
34
+ require 'redis' if defined?(::Redis)
35
+
36
+ class Tml::CacheAdapters::Redis < Tml::Cache
37
+
38
+ def initialize
39
+ cache_host, cache_port = Tml.config.cache[:host].split(':') if Tml.config.cache[:host]
40
+ cache_host ||= 'localhost'
41
+ cache_port ||= 6379
42
+
43
+ @cache = ::Redis.new(host: cache_host, port: cache_port)
44
+ end
45
+
46
+ def cache_name
47
+ "redis"
48
+ end
49
+
50
+ def read_only?
51
+ false
52
+ end
53
+
54
+ def fetch(key, opts = {})
55
+ data = @cache.get(versioned_key(key, opts))
56
+ if data
57
+ info("Cache hit: #{key}")
58
+ return data
59
+ end
60
+
61
+ info("Cache miss: #{key}")
62
+
63
+ return nil unless block_given?
64
+
65
+ data = yield
66
+
67
+ store(key, data)
68
+
69
+ data
70
+ rescue Exception => ex
71
+ warn("Failed to retrieve data: #{ex.message}")
72
+ return nil unless block_given?
73
+ yield
74
+ end
75
+
76
+ def store(key, data, opts = {})
77
+ info("Cache store: #{key}")
78
+ ttl = opts[:ttl] || Tml.config.cache[:timeout]
79
+ versioned_key = versioned_key(key, opts)
80
+
81
+ @cache.set(versioned_key, data)
82
+ @cache.expire(versioned_key, ttl) if ttl and ttl > 0
83
+ rescue Exception => ex
84
+ warn("Failed to store data: #{ex.message}")
85
+ data
86
+ end
87
+
88
+ def delete(key, opts = {})
89
+ info("Cache delete: #{key}")
90
+ @cache.del(versioned_key(key, opts))
91
+ rescue Exception => ex
92
+ warn("Failed to delete data: #{ex.message}")
93
+ key
94
+ end
95
+
96
+ def exist?(key, opts = {})
97
+ data = @cache.exist(versioned_key(key, opts))
98
+ not data.nil?
99
+ rescue Exception => ex
100
+ warn("Failed to check if key exists: #{ex.message}")
101
+ false
102
+ end
103
+
104
+ def clear(opts = {})
105
+ info('Cache clear has no effect')
106
+ end
107
+
108
+ end
data/lib/tml/config.rb ADDED
@@ -0,0 +1,410 @@
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
+ class << self
36
+ attr_accessor :config
37
+ end
38
+
39
+ # Initializes default config
40
+
41
+ def self.config
42
+ @config ||= Tml::Config.new
43
+ end
44
+
45
+ # Allows you to configure Tml
46
+ #
47
+ # Tml.configure do |config|
48
+ # config.application = {:key => "", :secret => ""}
49
+ #
50
+ # end
51
+ #
52
+
53
+ def self.configure
54
+ yield(self.config)
55
+ end
56
+
57
+ # Allows you to create a block to perform something on adjusted config settings
58
+ # Once the block exists, the config will be reset back to what it was before:
59
+ #
60
+ # Tml.with_config_settings do |config|
61
+ # config.format = :text
62
+ #
63
+ # Do something....
64
+ #
65
+ # end
66
+ #
67
+
68
+ def self.with_config_settings
69
+ old_config = @config.dup
70
+ yield(@config)
71
+ @config = old_config
72
+ end
73
+
74
+ # Acts as a global singleton that holds all Tml configuration
75
+ # The class can be extended with a different implementation, as long as the interface is supported
76
+ class Config
77
+ # Configuration Attributes
78
+ attr_accessor :enabled, :default_locale, :default_level, :format, :application, :context_rules, :logger, :cache, :default_tokens, :localization
79
+
80
+ # Used by Rails and Sinatra extensions
81
+ attr_accessor :current_locale_method, :current_user_method, :translator_options
82
+
83
+ # Used for IRB only
84
+ attr_accessor :submit_missing_keys_realtime
85
+
86
+ def initialize
87
+ @enabled = true
88
+ @default_locale = 'en'
89
+ @default_level = 0
90
+ @format = :html
91
+
92
+ # if running from IRB, make it default to TRUE
93
+ @submit_missing_keys_realtime = (%w(irb pry).include?($0 || ''))
94
+
95
+ @current_locale_method = :current_locale
96
+ @current_user_method = :current_user
97
+
98
+ @application = nil
99
+
100
+ @translator_options = {
101
+ debug: false,
102
+ debug_format_html: "<span style='font-size:20px;color:red;'>{</span> {$0} <span style='font-size:20px;color:red;'>}</span>",
103
+ debug_format: '{{{{$0}}}}',
104
+ split_sentences: false,
105
+ nodes: {
106
+ ignored: [],
107
+ scripts: %w(style script),
108
+ inline: %w(a span i b img strong s em u sub sup),
109
+ short: %w(i b),
110
+ splitters: %w(br hr)
111
+ },
112
+ attributes: {
113
+ labels: %w(title alt)
114
+ },
115
+ name_mapping: {
116
+ b: 'bold',
117
+ i: 'italic',
118
+ a: 'link',
119
+ img: 'picture'
120
+ },
121
+ data_tokens: {
122
+ special: false,
123
+ numeric: false,
124
+ numeric_name: 'num'
125
+ }
126
+ }
127
+
128
+ @context_rules = {
129
+ :number => {
130
+ :variables => {
131
+ }
132
+ },
133
+ :gender => {
134
+ :variables => {
135
+ '@gender' => 'gender',
136
+ }
137
+ },
138
+ :genders => {
139
+ :variables => {
140
+ '@genders' => lambda{|list| list.collect do |u|
141
+ u.is_a?(Hash) ? (u['gender'] || u[:gender]) : u.gender
142
+ end
143
+ },
144
+ '@size' => lambda{ |list| list.size }
145
+ }
146
+ },
147
+ :date => {
148
+ :variables => {
149
+ }
150
+ },
151
+ :time => {
152
+ :variables => {
153
+ }
154
+ },
155
+ :list => {
156
+ :variables => {
157
+ '@count' => lambda{|list| list.size}
158
+ }
159
+ },
160
+ }
161
+
162
+ @logger = {
163
+ :enabled => false,
164
+ :path => './log/tml.log',
165
+ :level => 'debug'
166
+ }
167
+
168
+ @cache = {
169
+ :enabled => false,
170
+ :host => 'localhost:11211',
171
+ :adapter => 'memcache',
172
+ :version => 1,
173
+ :timeout => 3600
174
+ }
175
+
176
+ @default_tokens = {
177
+ :html => {
178
+ :data => {
179
+ :ndash => "&ndash;", # –
180
+ :mdash => "&mdash;", # —
181
+ :iexcl => "&iexcl;", # ¡
182
+ :iquest => "&iquest;", # ¿
183
+ :quot => "&quot;", # "
184
+ :ldquo => "&ldquo;", # “
185
+ :rdquo => "&rdquo;", # ”
186
+ :lsquo => "&lsquo;", # ‘
187
+ :rsquo => "&rsquo;", # ’
188
+ :laquo => "&laquo;", # «
189
+ :raquo => "&raquo;", # »
190
+ :nbsp => "&nbsp;", # space
191
+ :lsaquo => "&lsaquo;", # ‹
192
+ :rsaquo => "&rsaquo;", # ›
193
+ :br => "<br/>", # line break
194
+ :lbrace => "{",
195
+ :rbrace => "}",
196
+ :trade => "&trade;", # TM
197
+ },
198
+ :decoration => {
199
+ :strong => "<strong>{$0}</strong>",
200
+ :bold => "<strong>{$0}</strong>",
201
+ :b => "<strong>{$0}</strong>",
202
+ :em => "<em>{$0}</em>",
203
+ :italic => "<i>{$0}</i>",
204
+ :i => "<i>{$0}</i>",
205
+ :link => "<a href='{$href}'>{$0}</a>",
206
+ :br => "<br>{$0}",
207
+ :strike => "<strike>{$0}</strike>",
208
+ :div => "<div id='{$id}' class='{$class}' style='{$style}'>{$0}</div>",
209
+ :span => "<span id='{$id}' class='{$class}' style='{$style}'>{$0}</span>",
210
+ :h1 => "<h1>{$0}</h1>",
211
+ :h2 => "<h2>{$0}</h2>",
212
+ :h3 => "<h3>{$0}</h3>",
213
+ }
214
+ },
215
+ :text => {
216
+ :data => {
217
+ :ndash => "–",
218
+ :mdash => "-",
219
+ :iexcl => "¡",
220
+ :iquest => "¿",
221
+ :quot => '"',
222
+ :ldquo => "“",
223
+ :rdquo => "”",
224
+ :lsquo => "‘",
225
+ :rsquo => "’",
226
+ :laquo => "«",
227
+ :raquo => "»",
228
+ :nbsp => " ",
229
+ :lsaquo => "‹",
230
+ :rsaquo => "›",
231
+ :br => "\n",
232
+ :lbrace => "{",
233
+ :rbrace => "}",
234
+ :trade => "™",
235
+ },
236
+ :decoration => {
237
+ :strong => "{$0}",
238
+ :bold => "{$0}",
239
+ :b => "{$0}",
240
+ :em => "{$0}",
241
+ :italic => "{$0}",
242
+ :i => "{$0}",
243
+ :link => "{$0}:{$1}",
244
+ :br => "\n{$0}",
245
+ :strike => "{$0}",
246
+ :div => "{$0}",
247
+ :span => "{$0}",
248
+ :h1 => "{$0}",
249
+ :h2 => "{$0}",
250
+ :h3 => "{$0}",
251
+ }
252
+ }
253
+ }
254
+
255
+ @localization = {
256
+ :default_day_names => ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
257
+ :default_abbr_day_names => ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
258
+ :default_month_names => ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
259
+ :default_abbr_month_names => ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
260
+ :custom_date_formats => {
261
+ :default => '%m/%d/%Y', # 07/4/2008
262
+ :short_numeric => '%m/%d', # 07/4
263
+ :short_numeric_year => '%m/%d/%y', # 07/4/08
264
+ :long_numeric => '%m/%d/%Y', # 07/4/2008
265
+ :verbose => '%A, %B %d, %Y', # Friday, July 4, 2008
266
+ :monthname => '%B %d', # July 4
267
+ :monthname_year => '%B %d, %Y', # July 4, 2008
268
+ :monthname_abbr => '%b %d', # Jul 4
269
+ :monthname_abbr_year => '%b %d, %Y', # Jul 4, 2008
270
+ :date_time => '%m/%d/%Y at %H:%M', # 01/03/1010 at 5:30
271
+ },
272
+ :token_mapping => {
273
+ "%a" => "{short_week_day_name}",
274
+ "%A" => "{week_day_name}",
275
+ "%b" => "{short_month_name}",
276
+ "%B" => "{month_name}",
277
+ "%p" => "{am_pm}",
278
+ "%d" => "{days}",
279
+ "%e" => "{day_of_month}",
280
+ "%j" => "{year_days}",
281
+ "%m" => "{months}",
282
+ "%W" => "{week_num}",
283
+ "%w" => "{week_days}",
284
+ "%y" => "{short_years}",
285
+ "%Y" => "{years}",
286
+ "%l" => "{trimed_hour}",
287
+ "%H" => "{full_hours}",
288
+ "%I" => "{short_hours}",
289
+ "%M" => "{minutes}",
290
+ "%S" => "{seconds}",
291
+ "%s" => "{since_epoch}"
292
+ }
293
+ }
294
+ end
295
+
296
+ def enabled?
297
+ enabled
298
+ end
299
+
300
+ def disabled?
301
+ not enabled?
302
+ end
303
+
304
+ def nested_value(hash, key, default_value = nil)
305
+ parts = key.split('.')
306
+ parts.each do |part|
307
+ return default_value unless hash[part.to_sym]
308
+ hash = hash[part.to_sym]
309
+ end
310
+ hash
311
+ end
312
+
313
+ def translator_option(key)
314
+ nested_value(self.translator_options, key)
315
+ end
316
+
317
+ def cache_enabled?
318
+ cache[:enabled].nil? || Tml.config.cache[:enabled]
319
+ end
320
+
321
+ #########################################################
322
+ ## Application
323
+ #########################################################
324
+
325
+ #def default_locale
326
+ # return Tml.session.application.default_locale if Tml.session.application
327
+ # @default_locale
328
+ #end
329
+ #
330
+ #def default_level
331
+ # return Tml.session.application.default_level if Tml.session.application
332
+ # @default_level
333
+ #end
334
+
335
+ def default_language
336
+ @default_language ||= begin
337
+ file = File.expand_path(File.join(File.dirname(__FILE__), '..', 'tml_core', 'languages', "#{Tml.config.default_locale}.json"))
338
+ Tml::Language.new(JSON.parse(File.read(file)))
339
+ end
340
+ end
341
+
342
+ def default_application
343
+ @default_application ||= Tml::Application.new(:host => Tml::Api::Client::API_HOST)
344
+ end
345
+
346
+ #########################################################
347
+ ## Decorations
348
+ #########################################################
349
+
350
+ def decorator_class
351
+ return Tml::Decorators::Html if @format == :html
352
+ Tml::Decorators::Default
353
+ end
354
+
355
+ def default_token_value(token_name, type = :data, format = :html)
356
+ default_tokens[format.to_sym][type.to_sym][token_name.to_sym]
357
+ end
358
+
359
+ def set_default_token(token_name, value, type = :data, format = :html)
360
+ default_tokens[format.to_sym] ||= {}
361
+ default_tokens[format.to_sym][type.to_sym] ||= {}
362
+ default_tokens[format.to_sym][type.to_sym][token_name.to_sym] = value
363
+ end
364
+
365
+ #########################################################
366
+ ## Localization
367
+ #########################################################
368
+
369
+ def strftime_symbol_to_token(symbol)
370
+ localization[:token_mapping][symbol]
371
+ end
372
+
373
+ def default_day_names
374
+ localization[:default_day_names]
375
+ end
376
+
377
+ def default_day_name(index)
378
+ "" + default_day_names[index]
379
+ end
380
+
381
+ def default_abbr_day_names
382
+ localization[:default_abbr_day_names]
383
+ end
384
+
385
+ def default_abbr_day_name(index)
386
+ '' + default_abbr_day_names[index]
387
+ end
388
+
389
+ def default_month_names
390
+ localization[:default_month_names]
391
+ end
392
+
393
+ def default_month_name(index)
394
+ '' + default_month_names[index]
395
+ end
396
+
397
+ def default_abbr_month_names
398
+ localization[:default_abbr_month_names]
399
+ end
400
+
401
+ def default_abbr_month_name(index)
402
+ '' + default_abbr_month_names[index]
403
+ end
404
+
405
+ def default_date_formats
406
+ localization[:custom_date_formats]
407
+ end
408
+
409
+ end
410
+ end