mustache_render 0.0.21 → 0.0.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/README.rdoc +22 -0
  2. data/lib/generators/mustache_render/install/templates/active_record/migration.rb +65 -0
  3. data/lib/generators/mustache_render/install/templates/config/initializers/mustache_render.rb +8 -14
  4. data/lib/generators/mustache_render/install/templates/models/active_record/mustache_render_folder.rb +6 -0
  5. data/lib/generators/mustache_render/install/templates/models/active_record/mustache_render_manager.rb +6 -0
  6. data/lib/generators/mustache_render/install/templates/models/active_record/mustache_render_template.rb +6 -0
  7. data/lib/generators/mustache_render/install/templates/models/active_record/mustache_render_template_version.rb +6 -0
  8. data/lib/generators/mustache_render/install_generator.rb +14 -2
  9. data/lib/mustache_render.rb +5 -14
  10. data/lib/mustache_render/ables.rb +7 -0
  11. data/lib/mustache_render/ables/render_able.rb +161 -0
  12. data/lib/mustache_render/config.rb +24 -62
  13. data/lib/mustache_render/errors.rb +5 -0
  14. data/lib/mustache_render/errors/mustache_template_miss_error.rb +6 -0
  15. data/lib/mustache_render/mustache.rb +85 -79
  16. data/lib/mustache_render/mustache/data.rb +155 -61
  17. data/lib/mustache_render/mustache/parser.rb +0 -4
  18. data/lib/mustache_render/mustache/template.rb +2 -7
  19. data/lib/mustache_render/populator.rb +7 -0
  20. data/lib/mustache_render/utils.rb +15 -0
  21. data/lib/mustache_render/{core_ext/base_controller_ext.rb → utils/action_controller_util.rb} +7 -6
  22. data/lib/mustache_render/utils/array_util.rb +15 -0
  23. data/lib/mustache_render/utils/fields_filter_util.rb +127 -0
  24. data/lib/mustache_render/version.rb +1 -1
  25. data/spec/lib/ables/render_able_spec.rb +183 -0
  26. data/spec/lib/mustache/basic_render_spec.rb +26 -1
  27. data/spec/lib/mustache/data_spec.rb +5 -5
  28. data/spec/lib/mustache/file_render_spec.rb +11 -2
  29. data/spec/lib/resources/templates/mustache_render_ables/1.mustache +11 -0
  30. data/spec/lib/utils/field_filter_spec.rb +71 -0
  31. data/spec/spec_helper.rb +0 -21
  32. metadata +69 -59
  33. data/README.md +0 -23
  34. data/lib/mustache_render/adapter.rb +0 -75
  35. data/lib/mustache_render/populator_base.rb +0 -88
  36. data/spec/lib/config_spec.rb +0 -14
  37. data/spec/lib/resources/templates/basic/8.mustache +0 -1
@@ -0,0 +1,5 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module MustacheRender
3
+ autoload :MustacheTemplateMissError, "#{File.dirname(__FILE__)}/errors/mustache_template_miss_error"
4
+ end
5
+
@@ -0,0 +1,6 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module MustacheRender
3
+ class MustacheTemplateMissError < ::RuntimeError
4
+
5
+ end
6
+ end
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'mustache_render/mustache/template'
3
- require 'mustache_render/mustache/context'
4
- require 'mustache_render/mustache/data'
2
+ require "#{File.dirname(__FILE__)}/mustache/template"
3
+ require "#{File.dirname(__FILE__)}/mustache/context"
4
+ require "#{File.dirname(__FILE__)}/mustache/data"
5
5
 
6
6
  module MustacheRender
7
7
  class Mustache
@@ -20,19 +20,21 @@ module MustacheRender
20
20
  end
21
21
 
22
22
  def render(data = template, ctx = {})
23
- impl_logger :level => :debug, :operation => 'MustacheRender::Mustache.render' do
24
- impl_template_render data, ctx
25
- end
26
- end
23
+ self.template = data
27
24
 
28
- # TODO: 语法检查,片段树
29
- def partials_tree
25
+ return self.template.render(context) if ctx == {}
30
26
 
27
+ begin
28
+ context.push(ctx)
29
+ self.template.render(context)
30
+ ensure
31
+ context.pop
32
+ end
31
33
  end
32
34
 
33
35
  # Context accessors.
34
36
  #
35
- # view = ::MustacheRender::Mustache.new
37
+ # view = Mustache.new
36
38
  # view[:name] = "Jon"
37
39
  # view.template = "Hi, {{name}}!"
38
40
  # view.render # => "Hi, Jon!"
@@ -51,15 +53,6 @@ module MustacheRender
51
53
  @context ||= Context.new(self)
52
54
  end
53
55
 
54
- # 使用default_media 进行渲染
55
- def self.impl_render(name, context={})
56
- self.new.send :impl_render, name, context
57
- end
58
-
59
- def impl_render name, context={}
60
- send "#{::MustacheRender.config.default_render_media}_render".to_sym, name, context
61
- end
62
-
63
56
  # Given a file name and an optional context, attempts to load and
64
57
  # render the file as a template.
65
58
  def self.file_render(name, context = {})
@@ -69,10 +62,22 @@ module MustacheRender
69
62
  # Given a file name and an optional context, attempts to load and
70
63
  # render the file as a template.
71
64
  def file_render(name, context = {})
72
- impl_logger :level => :debug, :operation => "#{self.class}.file_render" do
73
- @media = :file
74
- render(partial(name), context)
75
- end
65
+ @media = :file
66
+ render(partial(name), context)
67
+ end
68
+
69
+ def self.db_render(full_path, context={})
70
+ self.new.db_render full_path, context
71
+ end
72
+
73
+ def db_render(full_path, context={})
74
+ @media = :db
75
+ render(partial(full_path), context)
76
+ end
77
+
78
+ def impl_read_db_template name
79
+ db_template = ::MustacheRenderTemplate.find_with_full_path(name)
80
+ db_template.try :content
76
81
  end
77
82
 
78
83
  def self.generate_template_name(name, template_extension)
@@ -98,7 +103,7 @@ module MustacheRender
98
103
  File.read full_path
99
104
  rescue
100
105
  if config.raise_on_file_template_miss?
101
- raise ::MustacheRender::Mustache::TemplateMiss.new("read file template error: #{full_path}")
106
+ raise ::MustacheRender::MustacheTemplateMissError.new("miss read file template error: #{full_path}")
102
107
  else
103
108
  ''
104
109
  end
@@ -106,23 +111,10 @@ module MustacheRender
106
111
  end
107
112
 
108
113
  def read_template_from_media name, media
109
- # ::MustacheRender.logger.debug "MustacheRender render -> read template from #{media}: #{name}"
110
-
111
- impl_logger :level => :debug,
112
- :operation => "MustacheRender render -> read template from #{media}: #{name}" do
113
-
114
- case media
115
- when :file
116
- # if ::MustacheRender.config.file_template_cache?
117
- # self.class.fetch_partial_cache name, media, :expires_in => ::MustacheRender.config.file_template_cache_expires_in do
118
- # impl_read_file_template name
119
- # end
120
- # else
121
- # impl_read_file_template name
122
- # end
123
-
124
- impl_read_file_template name
125
- end
114
+ ::MustacheRender.logger.debug "MustacheRender render -> read template from #{media}: #{name}"
115
+ case media
116
+ when :file
117
+ impl_read_file_template name
126
118
  end
127
119
  end
128
120
 
@@ -132,6 +124,7 @@ module MustacheRender
132
124
  def partial(name)
133
125
  name = self.class.generate_template_name name, config.file_template_extension
134
126
 
127
+ # return self.read_template_from_media name, media
135
128
  @_cached_partials ||= {}
136
129
  (@_cached_partials[media] ||= {})[name] ||= self.read_template_from_media name, media
137
130
  end
@@ -149,6 +142,56 @@ module MustacheRender
149
142
  CGI.escapeHTML(str)
150
143
  end
151
144
 
145
+ #
146
+ # Private API
147
+ #
148
+
149
+ # When given a symbol or string representing a class, will try to produce an
150
+ # appropriate view class.
151
+ # e.g.
152
+ # Mustache.view_namespace = Hurl::Views
153
+ # Mustache.view_class(:Partial) # => Hurl::Views::Partial
154
+ def self.view_class(name)
155
+ if name != classify(name.to_s)
156
+ name = classify(name.to_s)
157
+ end
158
+
159
+ # Emptiness begets emptiness.
160
+ if name.to_s == ''
161
+ return Mustache
162
+ end
163
+
164
+ file_name = underscore(name)
165
+
166
+ name = "#{view_namespace}::#{name}"
167
+
168
+ if const = const_get!(name)
169
+ const
170
+ elsif File.exists?(file = "#{view_path}/#{file_name}.rb")
171
+ require "#{file}".chomp('.rb')
172
+ const_get!(name) || Mustache
173
+ else
174
+ Mustache
175
+ end
176
+ end
177
+
178
+ # Supercharged version of Module#const_get.
179
+ #
180
+ # Always searches under Object and can find constants by their full name,
181
+ # e.g. Mustache::Views::Index
182
+ #
183
+ # name - The full constant name to find.
184
+ #
185
+ # Returns the constant if found
186
+ # Returns nil if nothing is found
187
+ def self.const_get!(name)
188
+ name.split('::').inject(Object) do |klass, name|
189
+ klass.const_get(name)
190
+ end
191
+ rescue NameError
192
+ nil
193
+ end
194
+
152
195
  # Has this template already been compiled? Compilation is somewhat
153
196
  # expensive so it may be useful to check this before attempting it.
154
197
  def self.compiled?
@@ -180,7 +223,7 @@ module MustacheRender
180
223
  end.join('::')
181
224
  end
182
225
 
183
- # TemplatePartial => template_partial
226
+ # TemplatePartial => template_partial
184
227
  # Template::Partial => template/partial
185
228
  # Takes a string but defaults to using the current class' name.
186
229
  def self.underscore(classified = name)
@@ -219,42 +262,5 @@ module MustacheRender
219
262
  def self.inheritable_config_for(attr_name, default)
220
263
  superclass.respond_to?(attr_name) ? superclass.send(attr_name) : default
221
264
  end
222
-
223
- private
224
-
225
- def impl_logger options={}
226
- level = options[:level] || :debug
227
-
228
- result = nil
229
-
230
- if block_given?
231
- start_at = Time.now
232
- result = yield
233
- ms = ((Time.now - start_at) * 1000).to_i
234
- MustacheRender.logger.send level, impl_format_log_entry(
235
- "#{options[:operation]} (#{ms}ms)", options[:message]
236
- )
237
- end
238
-
239
- result
240
- end
241
-
242
- def impl_format_log_entry(operation, message = nil)
243
- " \033[4;34;1m#{operation}\033[0m \033[0;1m#{message}\033[0m"
244
- end
245
-
246
- def impl_template_render(data=template, ctx={})
247
- self.template = data
248
-
249
- return self.template.render(context) if ctx == {}
250
-
251
- begin
252
- context.push(ctx)
253
- self.template.render(context)
254
- ensure
255
- context.pop
256
- end
257
- end
258
-
259
265
  end
260
266
  end
@@ -1,93 +1,187 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module MustacheRender
3
- class Mustache
4
- # 将所有的key转为字符串
5
- class Data < ::Hash
6
- def initialize options = {}
7
- self.merge! options
3
+ class Mustache::Data < ::Hash
4
+ def initialize(options={})
5
+ self.merge! options
6
+ end
7
+
8
+ [:render, :file_render, :impl_render].each do |method_name|
9
+ define_method method_name do |path_or_template|
10
+ ::MustacheRender::Mustache.send method_name, path_or_template, self
8
11
  end
12
+ end
13
+
14
+ def []=(name, value)
15
+ super(name.to_sym, value)
16
+ end
17
+
18
+ def to_ary
19
+ end
9
20
 
10
- [:render, :file_render, :impl_render].each do |method_name|
11
- define_method method_name do |path_or_template|
12
- ::MustacheRender::Mustache.send method_name, path_or_template, self
21
+ def [](name)
22
+ super(name.to_sym)
23
+ end
24
+
25
+ def deep_merge(other_hash)
26
+ self.deep_dup.deep_merge!(other_hash)
27
+ end
28
+
29
+ # 深层的合并
30
+ def deep_merge!(other_hash)
31
+ other_hash = self.class.new(other_hash) unless other_hash.is_a?(self.class)
32
+
33
+ other_hash.each_pair do |k,v|
34
+ tv = self[k]
35
+
36
+ unless v.is_a?(self.class)
37
+ v = self.class.new(v) if v.is_a?(Hash)
13
38
  end
39
+
40
+ self[k] = tv.is_a?(self.class) && v.is_a?(self.class) ? tv.deep_merge(v) : v
14
41
  end
15
42
 
16
- def []=(name, value)
17
- result = super(name.to_s, value)
18
- self.each_pair do |k, v|
19
- impl_stringify_keys v
43
+ self
44
+ end
45
+
46
+ def deep_dup
47
+ impl_deep_dup self
48
+ end
49
+
50
+ def method_missing method_name, *args, &block
51
+ # 如果方法是赋值, 则直接赋值
52
+ if method_name.to_s.end_with?('=')
53
+ self[method_name.to_s.chop!] = args.first
54
+ else
55
+ result = self[method_name.to_sym]
56
+
57
+ if result.is_a?(Hash) && !(result.is_a?(self.class))
58
+ self[method_name] = self.class.new(result)
59
+ elsif result.nil?
60
+ self[method_name] = self.class.new
61
+ else
62
+ result
20
63
  end
21
- # self.stringify_keys!
22
- result
23
64
  end
65
+ end
24
66
 
25
- def [](name)
26
- super(name.to_s)
27
- end
67
+ def stringify_keys!
68
+ impl_stringify_keys! self
69
+ end
28
70
 
29
- # 深层复制
30
- def deep_dup
31
- duplicate = self.dup
32
- duplicate.each_pair do |k, v|
33
- tv = duplicate[k]
34
- duplicate[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_dup : v
35
- end
36
- duplicate
71
+ def symbolize_keys!
72
+ impl_symbolize_keys! self
73
+ end
74
+
75
+ #
76
+ # origin_hash_symbolize
77
+ # origin_hash_stringify
78
+ # origin_hash_symbolize! key全是 symbol的
79
+ # origin_hash_stringify! key全市 string 的
80
+ #
81
+ [:symbolize, :stringify].each do |method_name|
82
+ define_method "origin_hash_#{method_name}".to_sym do
83
+ self.deep_dup.send "origin_hash_#{method_name}!".to_sym
37
84
  end
38
85
 
39
- #
40
- # data = MustacheRender::Mustache::Data.new
41
- # data.site = {
42
- # :name => 'abc'
43
- # }
44
- #
45
- # 等价于
46
- #
47
- # data['site'] = {
48
- # :name => 'abc'
49
- # }
50
- #
51
- def method_missing method_name, *args, &block
52
- # 如果方法是赋值, 则直接赋值
53
- if method_name.to_s[-1,1] == "="
54
- self[method_name.to_s.chop!] = args.first
55
- else
56
- result = self[method_name.to_s]
57
-
58
- if result.is_a?(Hash)
59
- self[method_name.to_s] = Data.new(result)
60
- elsif result.nil? # 如果为空的话,则生成一个新的对象
61
- self[method_name.to_s] = Data.new {}
62
- else
63
- result
64
- end
65
- end
86
+ define_method "origin_hash_#{method_name}!".to_sym do
87
+ self.send "impl_origin_hash_#{method_name}".to_sym, self
66
88
  end
89
+ end
67
90
 
68
- def stringify_keys!
69
- raise 'not impl'
91
+ #
92
+ # deep_stringify_keys
93
+ # deep_stringify_keys!
94
+ #
95
+ [:stringify, :symbolize].each do |method_name|
96
+ method_name_impl = "impl_#{method_name}_keys".to_sym
97
+ method_name_new_soft = "deep_#{method_name}_keys".to_sym
98
+ method_name_new = "deep_#{method_name}_keys!".to_sym
99
+
100
+ define_method method_name_new_soft do
101
+ self.deep_dup.send method_name_new
70
102
  end
71
103
 
72
- def symbolize_keys!
73
- raise 'not impl'
104
+ define_method method_name_new do
105
+ tmp = self.send method_name_impl, self
106
+
107
+ tmp.keys.each do |key|
108
+ tmp[key] = self.send method_name_impl, tmp[key]
109
+ end
110
+
111
+ tmp
74
112
  end
113
+ end
75
114
 
76
- private
115
+ private
116
+
117
+ def impl_deep_dup v
118
+ if v.is_a?(::Hash)
119
+ tv = v.dup
120
+
121
+ v.each do |key, value|
122
+ tv[key] = impl_deep_dup value
123
+ end
124
+
125
+ tv
126
+ elsif v.is_a?(::Array)
127
+ v.map do |_v|
128
+ impl_deep_dup _v
129
+ end
130
+ else
131
+ v
132
+ end
133
+ end
77
134
 
78
- def impl_stringify_keys(v)
135
+ [:stringify, :symbolize].each do |method_name|
136
+ typify_method = {:symbolize => :to_sym, :stringify => :to_s}[method_name]
137
+ method_name_new = "impl_origin_hash_#{method_name}".to_sym
138
+ define_method method_name_new do |v|
79
139
  if v.is_a?(::Hash)
140
+ tv = Hash.new
141
+
80
142
  v.keys.each do |key|
81
- v[key.to_s] = v.delete(key) unless key.is_a?(::String)
143
+ tv[key.send(typify_method)] = self.send(method_name_new, v[key])
82
144
  end
145
+
146
+ tv
83
147
  elsif v.is_a?(::Array)
84
- v.each do |_v|
85
- impl_stringify_keys _v
148
+ v.map do |_v|
149
+ self.send(method_name_new, _v)
86
150
  end
151
+ else
152
+ v
87
153
  end
88
154
  end
155
+ end
156
+
157
+ [:stringify, :symbolize].each do |method_name|
158
+ typify_clazz = {:stringify => ::String, :symbolize => ::Hash}[method_name]
159
+ method_name_new = "impl_#{method_name}_keys".to_sym
160
+ typify_method = {:symbolize => :to_sym, :stringify => :to_s}[method_name]
161
+
162
+ define_method method_name_new do |v|
163
+ if v.is_a?(Hash)
164
+ v.keys.each do |key|
165
+ kv = v.delete key
89
166
 
167
+ unless key.is_a?(typify_clazz)
168
+ if(kv.is_a?(::Hash) && !(kv.is_a?(self.class)))
169
+ kv = self.class.new(kv)
170
+ end
171
+ end
172
+
173
+ v[key.send(typify_method)] = self.send method_name_new, kv
174
+ end
175
+ elsif v.is_a?(Array)
176
+ v = v.map do |_v|
177
+ self.send method_name_new, _v
178
+ end
179
+ end
180
+
181
+ v
182
+ end
90
183
  end
184
+
91
185
  end
92
186
  end
93
187