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,16 +1,11 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
require 'cgi'
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require "#{File.dirname(__FILE__)}/parser"
|
5
|
+
require "#{File.dirname(__FILE__)}/generator"
|
6
6
|
|
7
7
|
module MustacheRender
|
8
8
|
class Mustache
|
9
|
-
# 模板缺失
|
10
|
-
class TemplateMiss < ::RuntimeError
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
9
|
# A Template represents a Mustache template. It compiles and caches
|
15
10
|
# a raw string template into something usable.
|
16
11
|
#
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module MustacheRender
|
3
|
+
autoload :ActionControllerUtil, "#{File.dirname(__FILE__)}/utils/action_controller_util"
|
4
|
+
autoload :FieldsFilterUtil, "#{File.dirname(__FILE__)}/utils/fields_filter_util"
|
5
|
+
autoload :ArrayUtil, "#{File.dirname(__FILE__)}/utils/array_util"
|
6
|
+
end
|
7
|
+
|
8
|
+
if defined?(::ActionController::Base)
|
9
|
+
::ActionController::Base.send :include, ::MustacheRender::ActionControllerUtil
|
10
|
+
end
|
11
|
+
|
12
|
+
if defined?(::ActionView::Base)
|
13
|
+
::ActionView::Base.send :include, ::MustacheRender::ActionControllerUtil
|
14
|
+
end
|
15
|
+
|
data/lib/mustache_render/{core_ext/base_controller_ext.rb → utils/action_controller_util.rb}
RENAMED
@@ -1,10 +1,9 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
module MustacheRender
|
3
|
-
|
4
|
-
|
2
|
+
module MustacheRender
|
3
|
+
# include ::MustacheRender::ActionControllerUtil
|
4
|
+
module ActionControllerUtil
|
5
|
+
def self.included base
|
5
6
|
base.class_eval do
|
6
|
-
helper HelperMethods
|
7
|
-
|
8
7
|
extend ClassMethods
|
9
8
|
include InstanceMethods
|
10
9
|
end
|
@@ -24,7 +23,9 @@ module MustacheRender::CoreExt
|
|
24
23
|
# file_render template_path, data
|
25
24
|
#
|
26
25
|
[:render, :file_render, :impl_render].each do |method_name|
|
27
|
-
define_method "mustache_#{method_name}".to_sym do |path_or_template, data|
|
26
|
+
define_method "mustache_#{method_name}".to_sym do |path_or_template, *data|
|
27
|
+
data = data.first || Hash.new
|
28
|
+
|
28
29
|
impl_mustache_result_render method_name, path_or_template, data
|
29
30
|
end
|
30
31
|
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module MustacheRender
|
3
|
+
class FieldsFilterUtil
|
4
|
+
RULE_JOIN_GAP = '#'
|
5
|
+
|
6
|
+
attr_reader :rules, :rules_tree
|
7
|
+
|
8
|
+
# data = {
|
9
|
+
# :deals => [
|
10
|
+
# {
|
11
|
+
# :name => 'name_1',
|
12
|
+
# :title => 'title_1',
|
13
|
+
# :price => 23.4,
|
14
|
+
# :shops => [
|
15
|
+
# {
|
16
|
+
# :name => 'shop_1',
|
17
|
+
# :address => 'address 1'
|
18
|
+
# }
|
19
|
+
# ]
|
20
|
+
# }
|
21
|
+
# ],
|
22
|
+
# :shop => {
|
23
|
+
# :name => 1,
|
24
|
+
# :deals => [
|
25
|
+
# {
|
26
|
+
# :name => "deal_1"
|
27
|
+
# }
|
28
|
+
# ]
|
29
|
+
# },
|
30
|
+
# :deal => {
|
31
|
+
# :name => ''
|
32
|
+
# }
|
33
|
+
# }
|
34
|
+
#
|
35
|
+
# ########
|
36
|
+
# filter = {
|
37
|
+
# :default => {
|
38
|
+
# :deals => {
|
39
|
+
# :name => true
|
40
|
+
# }
|
41
|
+
# }
|
42
|
+
# }
|
43
|
+
#
|
44
|
+
# 转译配置语言
|
45
|
+
def initialize rule={}
|
46
|
+
@rules = {}
|
47
|
+
@rules_tree = {}
|
48
|
+
|
49
|
+
@empty = (
|
50
|
+
rule.is_a?(Hash) || rule.is_a?(Array)
|
51
|
+
) ? rule.empty? : true
|
52
|
+
|
53
|
+
parse_rules :rule => rule
|
54
|
+
|
55
|
+
@rules.freeze
|
56
|
+
@rules_tree.freeze
|
57
|
+
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def empty?
|
62
|
+
@empty
|
63
|
+
end
|
64
|
+
|
65
|
+
def present?
|
66
|
+
!(empty?)
|
67
|
+
end
|
68
|
+
|
69
|
+
def load formater=nil
|
70
|
+
if @rules_tree.key?(str = generate_string_formater(formater))
|
71
|
+
@rules_tree[str]
|
72
|
+
else
|
73
|
+
self.class.new
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def match?(formater=nil)
|
78
|
+
present? && !!at(formater)
|
79
|
+
end
|
80
|
+
|
81
|
+
alias :hit? :match?
|
82
|
+
|
83
|
+
def at(formater=nil)
|
84
|
+
@rules[generate_string_formater(formater)]
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def generate_string_formater formater
|
90
|
+
if formater.is_a?(Array)
|
91
|
+
formater.join(RULE_JOIN_GAP)
|
92
|
+
else
|
93
|
+
"#{formater}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def parse_rules options={}
|
98
|
+
path = "#{options[:path]}"
|
99
|
+
rule = options[:rule]
|
100
|
+
path_empty = path.strip.size == 0
|
101
|
+
|
102
|
+
case rule
|
103
|
+
when Hash
|
104
|
+
rule.each do |key, val|
|
105
|
+
_path = path_empty ? "#{key}" : "#{path}#{RULE_JOIN_GAP}#{key}"
|
106
|
+
@rules_tree[_path] = self.class.new(val)
|
107
|
+
@rules[_path] = parse_rules :path => _path, :rule => val
|
108
|
+
parse_rules :path => "#{_path}", :rule => val
|
109
|
+
end
|
110
|
+
when Array
|
111
|
+
rule.each do |rul|
|
112
|
+
parse_rules :path => "#{path}", :rule => rul
|
113
|
+
end
|
114
|
+
when NilClass
|
115
|
+
unless path_empty
|
116
|
+
@rules[path] = nil
|
117
|
+
@rules_tree[path] = nil
|
118
|
+
end
|
119
|
+
else
|
120
|
+
unless path_empty
|
121
|
+
@rules[path] = rule
|
122
|
+
@rules_tree[path] = rule
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe ::MustacheRender::RenderAble do
|
5
|
+
|
6
|
+
context '测试基本情况' do
|
7
|
+
module DefaultShopDataPopulator
|
8
|
+
def impl_to_mustache result, filter_util, options, &block
|
9
|
+
if filter_util.hit?("current_name")
|
10
|
+
result[:current_name] = 'ShopDataPopulator'
|
11
|
+
end
|
12
|
+
|
13
|
+
deals_filter_util = filter_util.load("deals")
|
14
|
+
|
15
|
+
if deals_filter_util.present?
|
16
|
+
result[:deals] = {}
|
17
|
+
|
18
|
+
if deals_filter_util.hit?("name")
|
19
|
+
result[:deals][:name] = self.name
|
20
|
+
end
|
21
|
+
|
22
|
+
if deals_filter_util.hit?("title")
|
23
|
+
result[:deals][:title] = self.title
|
24
|
+
end
|
25
|
+
|
26
|
+
if deals_filter_util.at('address') == :detail
|
27
|
+
result[:deals][:address] = "detail:#{self.address}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class ShopData
|
35
|
+
include ::MustacheRender::RenderAble::ForRecord
|
36
|
+
|
37
|
+
attr_reader :name, :age, :address, :title
|
38
|
+
|
39
|
+
def initialize param={}
|
40
|
+
@name = param[:name]
|
41
|
+
@age = param[:age]
|
42
|
+
@title = param[:title]
|
43
|
+
@address = param[:address]
|
44
|
+
end
|
45
|
+
|
46
|
+
self.load_mustache_populator(
|
47
|
+
:populators => DefaultShopDataPopulator
|
48
|
+
) do |config|
|
49
|
+
config.filters_util = {
|
50
|
+
:default => {
|
51
|
+
:deals => {
|
52
|
+
:name => false,
|
53
|
+
:title => true,
|
54
|
+
:address => true
|
55
|
+
},
|
56
|
+
:current_name => false
|
57
|
+
},
|
58
|
+
:array => {
|
59
|
+
:deals => {
|
60
|
+
:title => false,
|
61
|
+
:address => :detail
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'mustache_render Test' do
|
69
|
+
start = Time.now
|
70
|
+
|
71
|
+
a1 = ShopData.new
|
72
|
+
a2 = ShopData.new :name => 'a2', :address => 'address2'
|
73
|
+
a3 = ShopData.new :name => 'a3'
|
74
|
+
a4 = ShopData.new :name => 'a4'
|
75
|
+
a5 = ShopData.new :name => 'a5'
|
76
|
+
a6 = ShopData.new :name => 'a6'
|
77
|
+
a7 = ShopData.new :name => 'a7'
|
78
|
+
|
79
|
+
a = [a1, a2, a3, nil]
|
80
|
+
|
81
|
+
num = 1000
|
82
|
+
|
83
|
+
(1..num).each do |i|
|
84
|
+
a.mustache_render("", :filter => :array).should == ""
|
85
|
+
|
86
|
+
a.mustache_render(
|
87
|
+
"{{#any?}}any-true{{/any?}}{{#list}}{{#deals}}-address:{{address}}{{/deals}}{{/list}}",
|
88
|
+
:filter => :array
|
89
|
+
).should == "any-true-address:detail:-address:detail:address2-address:detail:"
|
90
|
+
|
91
|
+
a.mustache_file_render(
|
92
|
+
"/mustache_render_ables/1",
|
93
|
+
:filter => :array
|
94
|
+
).should == "<ul>\n <li>name: </li>\n <li>age: </li>\n <li>address: detail:</li>\n</ul>\n<ul>\n <li>name: </li>\n <li>age: </li>\n <li>address: detail:address2</li>\n</ul>\n<ul>\n <li>name: </li>\n <li>age: </li>\n <li>address: detail:</li>\n</ul>\n"
|
95
|
+
|
96
|
+
|
97
|
+
# a.to_mustache(:filter => :array).should == {
|
98
|
+
# :any? => true, :list => [
|
99
|
+
# {:nil? => false, :deals => {:address => "detail:"}},
|
100
|
+
# {:nil? => false, :deals => {:address => "detail:address2"}},
|
101
|
+
# {:nil? => false, :deals => {:address => "detail:"}},
|
102
|
+
# {:nil? => true}
|
103
|
+
# ], :pagination => {
|
104
|
+
# :support? => false
|
105
|
+
# }
|
106
|
+
# }
|
107
|
+
end
|
108
|
+
|
109
|
+
time = Time.now - start
|
110
|
+
puts "#{num}次执行时间mustache_render:#{time}"
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'array to_mustache Test' do
|
114
|
+
start = Time.now
|
115
|
+
|
116
|
+
a1 = ShopData.new
|
117
|
+
a2 = ShopData.new :name => 'a2', :address => 'address2'
|
118
|
+
a3 = ShopData.new :name => 'a3'
|
119
|
+
a4 = ShopData.new :name => 'a4'
|
120
|
+
a5 = ShopData.new :name => 'a5'
|
121
|
+
a6 = ShopData.new :name => 'a6'
|
122
|
+
a7 = ShopData.new :name => 'a7'
|
123
|
+
|
124
|
+
a = [a1, a2, a3, nil]
|
125
|
+
|
126
|
+
num = 10000
|
127
|
+
|
128
|
+
(1..num).each do |i|
|
129
|
+
a.to_mustache(:filter => :array).should == {
|
130
|
+
:any? => true, :list => [
|
131
|
+
{:nil? => false, :deals => {:address => "detail:"}},
|
132
|
+
{:nil? => false, :deals => {:address => "detail:address2"}},
|
133
|
+
{:nil? => false, :deals => {:address => "detail:"}},
|
134
|
+
{:nil? => true}
|
135
|
+
], :pagination => {
|
136
|
+
:support? => false
|
137
|
+
}
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
time = Time.now - start
|
142
|
+
puts "#{num}次执行时间array to_mustache:#{time}"
|
143
|
+
time.should < 1
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'class methods Test' do
|
147
|
+
ShopData.mustache_populator_config.is_a?(MustacheRender::RenderAble::MustachePopulatorConfig).should be_true
|
148
|
+
|
149
|
+
start = Time.now
|
150
|
+
|
151
|
+
(1..10000).each do |i|
|
152
|
+
a = ShopData.new :title => 'title_abc'
|
153
|
+
|
154
|
+
a.to_mustache.should == {
|
155
|
+
:deals => {
|
156
|
+
:title => "title_abc"
|
157
|
+
},
|
158
|
+
:nil? => false
|
159
|
+
}
|
160
|
+
|
161
|
+
a = ShopData.new(
|
162
|
+
:title => :title_bcd,
|
163
|
+
:name => :name_bcd
|
164
|
+
)
|
165
|
+
|
166
|
+
a.to_mustache.should == {
|
167
|
+
:deals => {
|
168
|
+
:title => :title_bcd
|
169
|
+
},
|
170
|
+
:nil? => false
|
171
|
+
}
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
(Time.now - start).should < 0.5
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'nil to_mustache' do
|
179
|
+
nil.to_mustache[:nil?].should == true
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
@@ -7,13 +7,38 @@ describe 'MustacheRender Render Basic Render' do
|
|
7
7
|
|
8
8
|
end
|
9
9
|
|
10
|
+
it "class extend test" do
|
11
|
+
class DealFormat < ::MustacheRender::Mustache
|
12
|
+
def data
|
13
|
+
'data1'
|
14
|
+
end
|
15
|
+
|
16
|
+
def render1
|
17
|
+
"render2"
|
18
|
+
end
|
19
|
+
|
20
|
+
def hello
|
21
|
+
{
|
22
|
+
:name => 'happy',
|
23
|
+
:age => 28
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
DealFormat.render("{{data}}").should == 'data1'
|
29
|
+
DealFormat.render("{{render1}}").should == 'render2'
|
30
|
+
DealFormat.render("{{hello.name}}").should == 'happy'
|
31
|
+
end
|
32
|
+
|
10
33
|
it 'basic render' do
|
11
34
|
viewer = ::MustacheRender::Mustache.new
|
12
35
|
|
13
36
|
viewer[:name] = 'Happy Wang'
|
14
37
|
viewer.template = '{{name}}'
|
15
38
|
viewer.render.should == 'Happy Wang'
|
16
|
-
|
39
|
+
expect {
|
40
|
+
viewer.file_render('basic/8').should == "in-8file:Happy Wang\n"
|
41
|
+
}.to raise_error(MustacheRender::MustacheTemplateMissError)
|
17
42
|
end
|
18
43
|
end
|
19
44
|
end
|