mustache_render 0.0.1 → 0.0.3
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/MIT-LICENSE +1 -1
- data/README.rdoc +20 -1
- data/lib/generators/mustache_render/migration/install_generator.rb +53 -0
- data/lib/generators/mustache_render/migration/templates/active_record/migration.rb +37 -0
- data/lib/generators/mustache_render/migration/templates/models/active_record/mustache_render_folder.rb +6 -0
- data/lib/generators/mustache_render/migration/templates/models/active_record/mustache_render_template.rb +6 -0
- data/lib/mustache_render.rb +26 -0
- data/lib/mustache_render/config.rb +22 -0
- data/lib/mustache_render/controllers/mustache_render/manager/base_controller.rb +16 -0
- data/lib/mustache_render/controllers/mustache_render/manager/folders_controller.rb +46 -0
- data/lib/mustache_render/controllers/mustache_render/manager/templates_controller.rb +53 -0
- data/lib/mustache_render/core_ext/base_controller_ext.rb +41 -0
- data/lib/mustache_render/models/mustache_render_folder_mixin.rb +128 -0
- data/lib/mustache_render/models/mustache_render_template_mixin.rb +44 -0
- data/lib/mustache_render/mustache.rb +314 -0
- data/lib/mustache_render/mustache/context.rb +144 -0
- data/lib/mustache_render/mustache/generator.rb +197 -0
- data/lib/mustache_render/mustache/parser.rb +265 -0
- data/lib/mustache_render/mustache/settings.rb +234 -0
- data/lib/mustache_render/mustache/template.rb +60 -0
- data/lib/mustache_render/version.rb +8 -1
- data/lib/mustache_render/views/layouts/mustache_render/manager/base.html.erb +14 -0
- data/lib/mustache_render/views/mustache_render/manager/folders/_form.html.erb +31 -0
- data/lib/mustache_render/views/mustache_render/manager/folders/edit.html.erb +11 -0
- data/lib/mustache_render/views/mustache_render/manager/folders/index.html.erb +9 -0
- data/lib/mustache_render/views/mustache_render/manager/folders/new.html.erb +8 -0
- data/lib/mustache_render/views/mustache_render/manager/folders/show.html.erb +44 -0
- data/lib/mustache_render/views/mustache_render/manager/templates/_form.html.erb +36 -0
- data/lib/mustache_render/views/mustache_render/manager/templates/edit.html.erb +15 -0
- data/lib/mustache_render/views/mustache_render/manager/templates/new.html.erb +12 -0
- data/lib/mustache_render/views/mustache_render/manager/templates/show.html.erb +33 -0
- metadata +106 -30
@@ -0,0 +1,234 @@
|
|
1
|
+
# Settings which can be configured for all view classes, a single
|
2
|
+
# view class, or a single Mustache instance.
|
3
|
+
module MustacheRender
|
4
|
+
class Mustache
|
5
|
+
|
6
|
+
#
|
7
|
+
# Template Path
|
8
|
+
#
|
9
|
+
|
10
|
+
# The template path informs your Mustache view where to look for its
|
11
|
+
# corresponding template. By default it's the current directory (".")
|
12
|
+
#
|
13
|
+
# A class named Stat with a template_path of "app/templates" will look
|
14
|
+
# for "app/templates/stat.mustache"
|
15
|
+
|
16
|
+
def self.template_path
|
17
|
+
@template_path ||= inheritable_config_for :template_path, '.'
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.template_path=(path)
|
21
|
+
@template_path = File.expand_path(path)
|
22
|
+
@template = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def template_path
|
26
|
+
@template_path ||= self.class.template_path
|
27
|
+
end
|
28
|
+
|
29
|
+
def template_path=(path)
|
30
|
+
@template_path = File.expand_path(path)
|
31
|
+
@template = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
# Alias for `template_path`
|
35
|
+
def self.path
|
36
|
+
template_path
|
37
|
+
end
|
38
|
+
alias_method :path, :template_path
|
39
|
+
|
40
|
+
# Alias for `template_path`
|
41
|
+
def self.path=(path)
|
42
|
+
self.template_path = path
|
43
|
+
end
|
44
|
+
alias_method :path=, :template_path=
|
45
|
+
|
46
|
+
|
47
|
+
#
|
48
|
+
# Template Extension
|
49
|
+
#
|
50
|
+
|
51
|
+
# A Mustache template's default extension is 'mustache', but this can be changed.
|
52
|
+
|
53
|
+
def self.template_extension
|
54
|
+
@template_extension ||= inheritable_config_for :template_extension, 'mustache'
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.template_extension=(template_extension)
|
58
|
+
@template_extension = template_extension
|
59
|
+
@template = nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def template_extension
|
63
|
+
@template_extension ||= self.class.template_extension
|
64
|
+
end
|
65
|
+
|
66
|
+
def template_extension=(template_extension)
|
67
|
+
@template_extension = template_extension
|
68
|
+
@template = nil
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
#
|
73
|
+
# Template Name
|
74
|
+
#
|
75
|
+
|
76
|
+
# The template name is the Mustache template file without any
|
77
|
+
# extension or other information. Defaults to `class_name`.
|
78
|
+
#
|
79
|
+
# You may want to change this if your class is named Stat but you want
|
80
|
+
# to re-use another template.
|
81
|
+
#
|
82
|
+
# class Stat
|
83
|
+
# self.template_name = "graphs" # use graphs.mustache
|
84
|
+
# end
|
85
|
+
|
86
|
+
def self.template_name
|
87
|
+
@template_name || underscore
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.template_name=(template_name)
|
91
|
+
@template_name = template_name
|
92
|
+
@template = nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def template_name
|
96
|
+
@template_name ||= self.class.template_name
|
97
|
+
end
|
98
|
+
|
99
|
+
def template_name=(template_name)
|
100
|
+
@template_name = template_name
|
101
|
+
@template = nil
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
#
|
106
|
+
# Template File
|
107
|
+
#
|
108
|
+
|
109
|
+
# The template file is the absolute path of the file Mustache will
|
110
|
+
# use as its template. By default it's ./class_name.mustache
|
111
|
+
|
112
|
+
# FIXME: remove here! for db store ############# happy ###
|
113
|
+
# def self.template_file
|
114
|
+
# @template_file || "#{path}/#{template_name}.#{template_extension}"
|
115
|
+
# end
|
116
|
+
|
117
|
+
# def self.template_file=(template_file)
|
118
|
+
# @template_file = template_file
|
119
|
+
# @template = nil
|
120
|
+
# end
|
121
|
+
|
122
|
+
# # The template file is the absolute path of the file Mustache will
|
123
|
+
# # use as its template. By default it's ./class_name.mustache
|
124
|
+
# def template_file
|
125
|
+
# @template_file || "#{path}/#{template_name}.#{template_extension}"
|
126
|
+
# end
|
127
|
+
|
128
|
+
# def template_file=(template_file)
|
129
|
+
# @template_file = template_file
|
130
|
+
# @template = nil
|
131
|
+
# end
|
132
|
+
|
133
|
+
|
134
|
+
#
|
135
|
+
# Template
|
136
|
+
#
|
137
|
+
|
138
|
+
# The template is the actual string Mustache uses as its template.
|
139
|
+
# There is a bit of magic here: what we get back is actually a
|
140
|
+
# Mustache::Template object, but you can still safely use `template=`
|
141
|
+
# with a string.
|
142
|
+
|
143
|
+
def self.template
|
144
|
+
@template ||= templateify(self.read_template(self.template_name))
|
145
|
+
# @template ||= templateify(File.read(template_file))
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.template=(template)
|
149
|
+
@template = templateify(template)
|
150
|
+
end
|
151
|
+
|
152
|
+
# The template can be set at the instance level.
|
153
|
+
def template
|
154
|
+
return @template if @template
|
155
|
+
|
156
|
+
## FIXME: add here
|
157
|
+
@template = self.class.template
|
158
|
+
|
159
|
+
# FIXME: remove here for db:store
|
160
|
+
# # If they sent any instance-level options use that instead of the class's.
|
161
|
+
# if @template_path || @template_extension || @template_name || @template_file
|
162
|
+
# @template = templateify(File.read(template_file))
|
163
|
+
# else
|
164
|
+
# @template = self.class.template
|
165
|
+
# end
|
166
|
+
end
|
167
|
+
|
168
|
+
def template=(template)
|
169
|
+
@template = templateify(template)
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
#
|
174
|
+
# Raise on context miss
|
175
|
+
#
|
176
|
+
|
177
|
+
# Should an exception be raised when we cannot find a corresponding method
|
178
|
+
# or key in the current context? By default this is false to emulate ctemplate's
|
179
|
+
# behavior, but it may be useful to enable when debugging or developing.
|
180
|
+
#
|
181
|
+
# If set to true and there is a context miss, `Mustache::ContextMiss` will
|
182
|
+
# be raised.
|
183
|
+
|
184
|
+
def self.raise_on_context_miss?
|
185
|
+
@raise_on_context_miss
|
186
|
+
end
|
187
|
+
|
188
|
+
def self.raise_on_context_miss=(boolean)
|
189
|
+
@raise_on_context_miss = boolean
|
190
|
+
end
|
191
|
+
|
192
|
+
# Instance level version of `Mustache.raise_on_context_miss?`
|
193
|
+
def raise_on_context_miss?
|
194
|
+
self.class.raise_on_context_miss? || @raise_on_context_miss
|
195
|
+
end
|
196
|
+
|
197
|
+
def raise_on_context_miss=(boolean)
|
198
|
+
@raise_on_context_miss = boolean
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
#
|
203
|
+
# View Namespace
|
204
|
+
#
|
205
|
+
|
206
|
+
# The constant under which Mustache will look for views when autoloading.
|
207
|
+
# By default the view namespace is `Object`, but it might be nice to set
|
208
|
+
# it to something like `Hurl::Views` if your app's main namespace is `Hurl`.
|
209
|
+
|
210
|
+
def self.view_namespace
|
211
|
+
@view_namespace ||= inheritable_config_for(:view_namespace, Object)
|
212
|
+
end
|
213
|
+
|
214
|
+
def self.view_namespace=(namespace)
|
215
|
+
@view_namespace = namespace
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
#
|
220
|
+
# View Path
|
221
|
+
#
|
222
|
+
|
223
|
+
# Mustache searches the view path for .rb files to require when asked to find a
|
224
|
+
# view class. Defaults to "."
|
225
|
+
|
226
|
+
def self.view_path
|
227
|
+
@view_path ||= inheritable_config_for(:view_path, '.')
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.view_path=(path)
|
231
|
+
@view_path = path
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
require 'mustache_render/mustache/parser'
|
4
|
+
require 'mustache_render/mustache/generator'
|
5
|
+
|
6
|
+
module MustacheRender
|
7
|
+
class Mustache
|
8
|
+
# A Template represents a Mustache template. It compiles and caches
|
9
|
+
# a raw string template into something usable.
|
10
|
+
#
|
11
|
+
# The idea is this: when handed a Mustache template, convert it into
|
12
|
+
# a Ruby string by transforming Mustache tags into interpolated
|
13
|
+
# Ruby.
|
14
|
+
#
|
15
|
+
# You shouldn't use this class directly, instead:
|
16
|
+
#
|
17
|
+
# >> Mustache.render(template, hash)
|
18
|
+
class Template
|
19
|
+
attr_reader :source
|
20
|
+
|
21
|
+
# Expects a Mustache template as a string along with a template
|
22
|
+
# path, which it uses to find partials.
|
23
|
+
def initialize(source)
|
24
|
+
@source = source
|
25
|
+
end
|
26
|
+
|
27
|
+
# Renders the `@source` Mustache template using the given
|
28
|
+
# `context`, which should be a simple hash keyed with symbols.
|
29
|
+
#
|
30
|
+
# The first time a template is rendered, this method is overriden
|
31
|
+
# and from then on it is "compiled". Subsequent calls will skip
|
32
|
+
# the compilation step and run the Ruby version of the template
|
33
|
+
# directly.
|
34
|
+
def render(context)
|
35
|
+
# Compile our Mustache template into a Ruby string
|
36
|
+
compiled = "def render(ctx) #{compile} end"
|
37
|
+
|
38
|
+
# Here we rewrite ourself with the interpolated Ruby version of
|
39
|
+
# our Mustache template so subsequent calls are very fast and
|
40
|
+
# can skip the compilation stage.
|
41
|
+
instance_eval(compiled, __FILE__, __LINE__ - 1)
|
42
|
+
|
43
|
+
# Call the newly rewritten version of #render
|
44
|
+
render(context)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Does the dirty work of transforming a Mustache template into an
|
48
|
+
# interpolation-friendly Ruby string.
|
49
|
+
def compile(src = @source)
|
50
|
+
Generator.new.compile(tokens(src))
|
51
|
+
end
|
52
|
+
alias_method :to_s, :compile
|
53
|
+
|
54
|
+
# Returns an array of tokens for a given template.
|
55
|
+
def tokens(src = @source)
|
56
|
+
Parser.new.compile(src)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>MustacheRender Manager Center</title>
|
5
|
+
<%#= stylesheet_link_tag "application", :media => "all" %>
|
6
|
+
<%#= javascript_include_tag "application" %>
|
7
|
+
<%#= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<% if @mustache_render_folder.errors.any? %>
|
2
|
+
<div id="error_explanation">
|
3
|
+
<h2><%= pluralize(@mustache_render_folder.errors.count, "error") %> 个问题导致不能保存:</h2>
|
4
|
+
|
5
|
+
<ul>
|
6
|
+
<% @mustache_render_folder.errors.full_messages.each do |msg| %>
|
7
|
+
<li><%= msg %></li>
|
8
|
+
<% end %>
|
9
|
+
</ul>
|
10
|
+
</div>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<div class="field">
|
14
|
+
<%= f.label :name %><br />
|
15
|
+
<%= f.text_field :name %>
|
16
|
+
</div>
|
17
|
+
|
18
|
+
<div class="field">
|
19
|
+
<%= f.label :parent_id %><br />
|
20
|
+
<%= f.select :parent_id, MustacheRenderFolder.nested_set_select_options(nil, @mustache_render_folder, :include_blank => true) %>
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<div class="field">
|
24
|
+
<%= f.label :note %><br />
|
25
|
+
<%= f.text_area :note, :rows => 5 %>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<div class="actions">
|
29
|
+
<%= f.submit %>
|
30
|
+
</div>
|
31
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<h1>编辑模板文件夹</h1>
|
2
|
+
|
3
|
+
<% form_for(@mustache_render_folder, :url => mustache_render_manager_folder_url(@mustache_render_folder)) do |f| %>
|
4
|
+
|
5
|
+
<%= render :partial => 'form', :locals => { :f => f } %>
|
6
|
+
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<%= link_to "返回列表", mustache_render_manager_folders_url %>
|
10
|
+
<%= link_to "取消编辑", mustache_render_manager_folder_url(@mustache_render_folder) %>
|
11
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<h1>模板文件夹列表</h1>
|
2
|
+
|
3
|
+
<%= link_to '新建', new_mustache_render_manager_folder_url %>
|
4
|
+
|
5
|
+
<% MustacheRenderFolder.nested_set_options do |folder| %>
|
6
|
+
<div>
|
7
|
+
<%= link_to h("#{'- ' * folder.level}#{folder.name}"), mustache_render_manager_folder_url(:id => folder.id) %>
|
8
|
+
</div>
|
9
|
+
<% end %>
|
@@ -0,0 +1,44 @@
|
|
1
|
+
<h1>模板文件夹详情</h1>
|
2
|
+
|
3
|
+
<div>
|
4
|
+
<% @mustache_render_folder.ancestors.each do |folder| %>
|
5
|
+
<%= link_to h("#{folder.name}"), mustache_render_manager_folder_url(folder) %> >>
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
<b><%= h "#{@mustache_render_folder.name}" %></b>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<div>
|
12
|
+
<div class='field'>
|
13
|
+
<b>全路径:</b> <%= h "#{@mustache_render_folder.full_path}" %>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<div class='field'>
|
17
|
+
<b>备注:</b> <br/>
|
18
|
+
<%= h "#{@mustache_render_folder.note}" %>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<div class='folders-list'>
|
23
|
+
|
24
|
+
</div>
|
25
|
+
|
26
|
+
<h3>模板文件列表</h3>
|
27
|
+
<div class='templates-list'>
|
28
|
+
<% if @mustache_render_templates.any? %>
|
29
|
+
<% @mustache_render_templates.each do |template| %>
|
30
|
+
<div class='template-item'>
|
31
|
+
<%= link_to h("#{template.name}"), mustache_render_manager_folder_template_url(:folder_id => template.folder_id, :id => template.id) %>
|
32
|
+
</div>
|
33
|
+
<% end %>
|
34
|
+
<% else %>
|
35
|
+
<div class='empty-list'>
|
36
|
+
没有模板文件
|
37
|
+
</div>
|
38
|
+
<% end %>
|
39
|
+
</div>
|
40
|
+
|
41
|
+
<%= link_to "新建模板文件", new_mustache_render_manager_folder_template_url(:folder_id => @mustache_render_folder.id) %>
|
42
|
+
<%= link_to "新建文件夹", new_mustache_render_manager_folder_url(:parent_id => @mustache_render_folder.id) %>
|
43
|
+
<%= link_to "编辑", edit_mustache_render_manager_folder_url(@mustache_render_folder) %>
|
44
|
+
<%= link_to "返回列表", mustache_render_manager_folders_url %>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<% if @mustache_render_template.errors.any? %>
|
2
|
+
<div id="error_explanation">
|
3
|
+
<h2><%= pluralize(@mustache_render_template.errors.count, "error") %> 个问题导致不能保存:</h2>
|
4
|
+
|
5
|
+
<ul>
|
6
|
+
<% @mustache_render_template.errors.full_messages.each do |msg| %>
|
7
|
+
<li><%= msg %></li>
|
8
|
+
<% end %>
|
9
|
+
</ul>
|
10
|
+
</div>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<div class="field">
|
14
|
+
<%= f.label :name %><br />
|
15
|
+
<%= f.text_field :name %>
|
16
|
+
</div>
|
17
|
+
|
18
|
+
<div class="field">
|
19
|
+
<%= f.label :folder_id %><br />
|
20
|
+
<%= f.select :folder_id, MustacheRenderFolder.nested_set_select_options() %>
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<div class="field">
|
24
|
+
<%= f.label :content %><br />
|
25
|
+
<%= f.text_area :content %>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<div class="field">
|
29
|
+
<%= f.label :note %><br />
|
30
|
+
<%= f.text_area :note, :rows => 5 %>
|
31
|
+
</div>
|
32
|
+
|
33
|
+
<div class="actions">
|
34
|
+
<%= f.submit %>
|
35
|
+
</div>
|
36
|
+
|