mustache_render 0.0.21 → 0.0.22
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.
- data/README.rdoc +22 -0
- data/lib/generators/mustache_render/install/templates/active_record/migration.rb +65 -0
- data/lib/generators/mustache_render/install/templates/config/initializers/mustache_render.rb +8 -14
- data/lib/generators/mustache_render/install/templates/models/active_record/mustache_render_folder.rb +6 -0
- data/lib/generators/mustache_render/install/templates/models/active_record/mustache_render_manager.rb +6 -0
- data/lib/generators/mustache_render/install/templates/models/active_record/mustache_render_template.rb +6 -0
- data/lib/generators/mustache_render/install/templates/models/active_record/mustache_render_template_version.rb +6 -0
- data/lib/generators/mustache_render/install_generator.rb +14 -2
- data/lib/mustache_render.rb +5 -14
- data/lib/mustache_render/ables.rb +7 -0
- data/lib/mustache_render/ables/render_able.rb +161 -0
- data/lib/mustache_render/config.rb +24 -62
- data/lib/mustache_render/errors.rb +5 -0
- data/lib/mustache_render/errors/mustache_template_miss_error.rb +6 -0
- data/lib/mustache_render/mustache.rb +85 -79
- data/lib/mustache_render/mustache/data.rb +155 -61
- data/lib/mustache_render/mustache/parser.rb +0 -4
- data/lib/mustache_render/mustache/template.rb +2 -7
- data/lib/mustache_render/populator.rb +7 -0
- data/lib/mustache_render/utils.rb +15 -0
- data/lib/mustache_render/{core_ext/base_controller_ext.rb → utils/action_controller_util.rb} +7 -6
- data/lib/mustache_render/utils/array_util.rb +15 -0
- data/lib/mustache_render/utils/fields_filter_util.rb +127 -0
- data/lib/mustache_render/version.rb +1 -1
- data/spec/lib/ables/render_able_spec.rb +183 -0
- data/spec/lib/mustache/basic_render_spec.rb +26 -1
- data/spec/lib/mustache/data_spec.rb +5 -5
- data/spec/lib/mustache/file_render_spec.rb +11 -2
- data/spec/lib/resources/templates/mustache_render_ables/1.mustache +11 -0
- data/spec/lib/utils/field_filter_spec.rb +71 -0
- data/spec/spec_helper.rb +0 -21
- metadata +69 -59
- data/README.md +0 -23
- data/lib/mustache_render/adapter.rb +0 -75
- data/lib/mustache_render/populator_base.rb +0 -88
- data/spec/lib/config_spec.rb +0 -14
- data/spec/lib/resources/templates/basic/8.mustache +0 -1
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
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
|
-
|
24
|
-
impl_template_render data, ctx
|
25
|
-
end
|
26
|
-
end
|
23
|
+
self.template = data
|
27
24
|
|
28
|
-
|
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 =
|
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
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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::
|
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
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
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
|
-
#
|
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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
67
|
+
def stringify_keys!
|
68
|
+
impl_stringify_keys! self
|
69
|
+
end
|
28
70
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
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
|
-
|
69
|
-
|
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
|
-
|
73
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
85
|
-
|
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
|
|