mustache 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## 0.4.0 (2009-10-27)
2
+
3
+ * Stopped raising context miss exceptions by default
4
+ * Added `Mustache.raise_on_context_miss` setting (defaults to false)
5
+ * Throw Mustache::ContextMiss when raise_on_context_miss is true and
6
+ we encounter a miss.
7
+ * The default template extension is now "mustache" (instead of "html").
8
+ * Added the `view_namespace` and `view_path` settings to `Mustache`
9
+ * Added `Mustache.view_class` method which autoloads a class using the
10
+ new `view_namespace` and `view_path` settings. Should be used by
11
+ plugin developers.
12
+ * Updated the Sinatra extension to use the new `view_class` method
13
+ * Unclosed sections now throw a helpful error message
14
+ * Report line numbers on unclosed section errors
15
+ * Added Rack::Bug panel
16
+
1
17
  ## 0.3.2 (2009-10-19)
2
18
 
3
19
  * Bugfix: Partials in Sinatra were using the wrong path.
data/README.md CHANGED
@@ -103,9 +103,11 @@ The most basic tag is the variable. A `{{name}}` tag in a basic
103
103
  template will try to call the `name` method on your view. If there is
104
104
  no `name` method, an exception will be raised.
105
105
 
106
- All variables are HTML escaped by default. If you want, for some
107
- reason, to return unescaped HTML you can use the triple mustache:
108
- `{{{name}}}`.
106
+ All variables are HTML escaped by default. If you want to return
107
+ unescaped HTML, use the triple mustache: `{{{name}}}`.
108
+
109
+ By default a variable "miss" returns an empty string. You can
110
+ configure this by setting `Mustache.raise_on_context_miss` to true.
109
111
 
110
112
  ### Boolean Sections
111
113
 
@@ -215,7 +217,7 @@ ctemplate and friends want you to hand a dictionary to the template
215
217
  processor. Mustache supports a similar concept. Feel free to mix the
216
218
  class-based and this more procedural style at your leisure.
217
219
 
218
- Given this template (winner.html):
220
+ Given this template (winner.mustache):
219
221
 
220
222
  Hello {{name}}
221
223
  You have just won ${{value}}!
@@ -247,7 +249,7 @@ A word on templates. By default, a view will try to find its template
247
249
  on disk by searching for an HTML file in the current directory that
248
250
  follows the classic Ruby naming convention.
249
251
 
250
- TemplatePartial => ./template_partial.html
252
+ TemplatePartial => ./template_partial.mustache
251
253
 
252
254
  You can set the search path using `Mustache.template_path`. It can be set on a
253
255
  class by class basis:
@@ -257,13 +259,13 @@ class by class basis:
257
259
  ... etc ...
258
260
  end
259
261
 
260
- Now `Simple` will look for `simple.html` in the directory it resides
262
+ Now `Simple` will look for `simple.mustache` in the directory it resides
261
263
  in, no matter the cwd.
262
264
 
263
265
  If you want to just change what template is used you can set
264
266
  `Mustache.template_file` directly:
265
267
 
266
- Simple.template_file = './blah.html'
268
+ Simple.template_file = './blah.mustache'
267
269
 
268
270
  Mustache also allows you to define the extension it'll use.
269
271
 
@@ -283,6 +285,15 @@ Or set a different template for a single instance:
283
285
  Whatever works.
284
286
 
285
287
 
288
+ Views
289
+ -----
290
+
291
+ Mustache supports a bit of magic when it comes to views. If you're
292
+ authoring a plugin or extension for a web framework (Sinatra, Rails,
293
+ etc), check out the `view_namespace` and `view_path` settings on the
294
+ `Mustache` class. They will surely provide needed assistance.
295
+
296
+
286
297
  Helpers
287
298
  -------
288
299
 
@@ -364,6 +375,23 @@ An example Sinatra application is also provided:
364
375
  <http://github.com/defunkt/mustache-sinatra-example>
365
376
 
366
377
 
378
+ [Rack::Bug][4]
379
+ ---------
380
+
381
+ Mustache also ships with a `Rack::Bug` panel. In your `config.ru` add
382
+ the following code:
383
+
384
+ require 'rack/bug/panels/mustache_panel'
385
+ use Rack::Bug::MustachePanel
386
+
387
+ Using Rails? Add this to your initializer or environment file:
388
+
389
+ require 'rack/bug/panels/mustache_panel'
390
+ config.middleware.use "Rack::Bug::MustachePanel"
391
+
392
+ [![Rack::Bug](http://img.skitch.com/20091027-xyf4h1yxnefpp7usyddrcmc7dn.png)][5]
393
+
394
+
367
395
  Vim
368
396
  ---
369
397
 
@@ -405,3 +433,5 @@ Meta
405
433
  [1]: http://code.google.com/p/google-ctemplate/
406
434
  [2]: http://www.ivan.fomichev.name/2008/05/erlang-template-engine-prototype.html
407
435
  [3]: http://google-ctemplate.googlecode.com/svn/trunk/doc/howto.html
436
+ [4]: http://github.com/brynary/rack-bug/
437
+ [5]: http://img.skitch.com/20091027-n8pxwwx8r61tc318a15q1n6m14.png
@@ -0,0 +1 @@
1
+ <h1>{{title}}</h1>
@@ -0,0 +1,17 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'mustache'
3
+
4
+ module TestViews
5
+ class Namespaced < Mustache
6
+ self.path = File.dirname(__FILE__)
7
+
8
+ def title
9
+ "Dragon < Tiger"
10
+ end
11
+ end
12
+ end
13
+
14
+
15
+ if $0 == __FILE__
16
+ puts TestViews::Namespaced.to_html
17
+ end
@@ -7,7 +7,7 @@ require 'mustache/context'
7
7
  # The typical Mustache workflow is as follows:
8
8
  #
9
9
  # * Create a Mustache subclass: class Stats < Mustache
10
- # * Create a template: stats.html
10
+ # * Create a template: stats.mustache
11
11
  # * Instantiate an instance: view = Stats.new
12
12
  # * Render that instance: view.render
13
13
  #
@@ -30,12 +30,12 @@ require 'mustache/context'
30
30
  # looking for a template. By default it is "."
31
31
  # Setting it to /usr/local/templates, for example, means (given all
32
32
  # other settings are default) a Mustache subclass `Stats` will try to
33
- # load /usr/local/templates/stats.html
33
+ # load /usr/local/templates/stats.mustache
34
34
  #
35
35
  # * template_extension
36
36
  #
37
37
  # The `template_extension` is the extension Mustache uses when looking
38
- # for template files. By default it is "html"
38
+ # for template files. By default it is "mustache"
39
39
  #
40
40
  # * template_file
41
41
  #
@@ -56,6 +56,19 @@ require 'mustache/context'
56
56
  # view.template = "Hi, {{person}}!"
57
57
  # view[:person] = 'Mom'
58
58
  # view.render # => Hi, mom!
59
+ #
60
+ # * view_namespace
61
+ #
62
+ # To make life easy on those developing Mustache plugins for web frameworks or
63
+ # other libraries, Mustache will attempt to load view classes (i.e. Mustache
64
+ # subclasses) using the `view_class` class method. The `view_namespace` tells
65
+ # Mustache under which constant view classes live. By default it is `Object`.
66
+ #
67
+ # * view_path
68
+ #
69
+ # Similar to `template_path`, the `view_path` option tells Mustache where to look
70
+ # for files containing view classes when using the `view_class` method.
71
+ #
59
72
  class Mustache
60
73
  # Helper method for quickly instantiating and rendering a view.
61
74
  def self.render(*args)
@@ -93,9 +106,9 @@ class Mustache
93
106
  self.template_path = path
94
107
  end
95
108
 
96
- # A Mustache template's default extension is 'html'
109
+ # A Mustache template's default extension is 'mustache'
97
110
  def self.template_extension
98
- @template_extension ||= 'html'
111
+ @template_extension ||= 'mustache'
99
112
  end
100
113
 
101
114
  def self.template_extension=(template_extension)
@@ -104,7 +117,7 @@ class Mustache
104
117
  end
105
118
 
106
119
  # The template file is the absolute path of the file Mustache will
107
- # use as its template. By default it's ./class_name.html
120
+ # use as its template. By default it's ./class_name.mustache
108
121
  def self.template_file
109
122
  @template_file || "#{path}/#{underscore}.#{template_extension}"
110
123
  end
@@ -126,6 +139,75 @@ class Mustache
126
139
  @template = templateify(template)
127
140
  end
128
141
 
142
+ # The constant under which Mustache will look for views. By default it's
143
+ # `Object`, but it might be nice to set it to something like `Hurl::Views` if
144
+ # your app's main namespace is `Hurl`.
145
+ def self.view_namespace
146
+ @view_namespace || Object
147
+ end
148
+
149
+ def self.view_namespace=(namespace)
150
+ @view_namespace = namespace
151
+ end
152
+
153
+ # Mustache searches the view path for .rb files to require when asked to find a
154
+ # view class. Defaults to "."
155
+ def self.view_path
156
+ @view_path ||= '.'
157
+ end
158
+
159
+ def self.view_path=(path)
160
+ @view_path = path
161
+ end
162
+
163
+ # When given a symbol or string representing a class, will try to produce an
164
+ # appropriate view class.
165
+ # e.g.
166
+ # Mustache.view_namespace = Hurl::Views
167
+ # Mustache.view_class(:Partial) # => Hurl::Views::Partial
168
+ def self.view_class(name)
169
+ if name != classify(name.to_s)
170
+ name = classify(name.to_s)
171
+ end
172
+
173
+ # Emptiness begets emptiness.
174
+ if name.to_s == ''
175
+ return Mustache
176
+ end
177
+
178
+ file_name = underscore(name)
179
+ namespace = view_namespace
180
+
181
+ if namespace.const_defined?(:Views) && namespace::Views.const_defined?(name)
182
+ namespace::Views.const_get(name)
183
+ elsif namespace.const_defined?(name)
184
+ namespace.const_get(name)
185
+ elsif File.exists?(file = "#{view_path}/#{file_name}.rb")
186
+ require "#{file}".chomp('.rb')
187
+ if namespace.const_defined?(:Views)
188
+ namespace::Views.const_get(name)
189
+ else
190
+ namespace.const_get(name)
191
+ end
192
+ else
193
+ Mustache
194
+ end
195
+ end
196
+
197
+ # Should an exception be raised when we cannot find a corresponding method
198
+ # or key in the current context? By default this is false to emulate ctemplate's
199
+ # behavior, but it may be useful to enable when debugging or developing.
200
+ #
201
+ # If set to true and there is a context miss, `Mustache::ContextMiss` will
202
+ # be raised.
203
+ def self.raise_on_context_miss?
204
+ @raise_on_context_miss
205
+ end
206
+
207
+ def self.raise_on_context_miss=(boolean)
208
+ @raise_on_context_miss = boolean
209
+ end
210
+
129
211
  # Has this template already been compiled? Compilation is somewhat
130
212
  # expensive so it may be useful to check this before attempting it.
131
213
  def self.compiled?
@@ -178,6 +260,12 @@ class Mustache
178
260
  @template = templateify(template)
179
261
  end
180
262
 
263
+ # Instance level version of `Mustache.raise_on_context_miss?`
264
+ def raise_on_context_miss?
265
+ self.class.raise_on_context_miss? || @raise_on_context_miss
266
+ end
267
+ attr_writer :raise_on_context_miss
268
+
181
269
  # A helper method which gives access to the context at a given time.
182
270
  # Kind of a hack for now, but useful when you're in an iterating section
183
271
  # and want access to the hash currently being iterated over.
@@ -1,4 +1,14 @@
1
1
  class Mustache
2
+ # A ContextMiss is raised whenever a tag's target can not be found
3
+ # in the current context if `Mustache#raise_on_context_miss?` is
4
+ # set to true.
5
+ #
6
+ # For example, if your View class does not respond to `music` but
7
+ # your template contains a `{{template}}` tag this exception will be raised.
8
+ #
9
+ # By default it is not raised. See Mustache.raise_on_context_miss.
10
+ class ContextMiss < RuntimeError; end
11
+
2
12
  # A Context represents the context which a Mustache template is
3
13
  # executed within. All Mustache tags reference keys in the Context.
4
14
  class Context < Hash
@@ -14,8 +24,10 @@ class Mustache
14
24
  super(name.to_s)
15
25
  elsif @mustache.respond_to?(name)
16
26
  @mustache.send(name)
27
+ elsif @mustache.raise_on_context_miss?
28
+ raise ContextMiss.new("Can't find #{name} in #{@mustache.inspect}")
17
29
  else
18
- raise "Can't find #{name} in #{@mustache.inspect}"
30
+ ''
19
31
  end
20
32
  end
21
33
  end
@@ -49,38 +49,18 @@ class Mustache
49
49
  # This is called by Sinatra's `render` with the proper paths
50
50
  # and, potentially, a block containing a sub-view
51
51
  def render_mustache(template, data, opts, locals, &block)
52
- name = Mustache.classify(template.to_s)
52
+ # If you have Hurl::App::Views, namespace should be set to Hurl::App.
53
+ Mustache.view_namespace = options.namespace
53
54
 
54
- # This is a horrible hack but we need it to know under which namespace
55
- # Views is located. If you have Hurl::App::Views, namespace should be
56
- # set to Hurl:App.
57
- namespace = options.namespace
55
+ # This is probably the same as options.views, but we'll set it anyway.
56
+ # It's used to tell Mustache where to look for view classes.
57
+ Mustache.view_path = options.mustaches
58
58
 
59
- if namespace.const_defined?(:Views) && namespace::Views.const_defined?(name)
60
- # First try to find the existing view,
61
- # e.g. Hurl::Views::Index
62
- klass = namespace::Views.const_get(name)
59
+ # Grab the class!
60
+ klass = Mustache.view_class(template)
63
61
 
64
- elsif File.exists?(file = "#{options.mustaches}/#{template}.rb")
65
- # Couldn't find it - try to require the file if it exists, then
66
- # load in the view.
67
- require "#{file}".chomp('.rb')
68
- klass = namespace::Views.const_get(name)
69
-
70
- # compile and cache the template
71
- klass.template = data
72
-
73
- else
74
- # Still nothing. Use the stache.
75
- klass = Mustache
76
-
77
- end
78
-
79
- # Tell the view class its extension and path so finding partials
80
- # works as expected.
81
- if klass.template_extension != 'mustache'
82
- klass.template_extension = 'mustache'
83
- end
62
+ # Only cache the data if this isn't the generic base class.
63
+ klass.template = data unless klass == Mustache
84
64
 
85
65
  # Confusingly Sinatra's `views` setting tells Mustache where the
86
66
  # templates are found. It's fine, blame Chris.
@@ -9,9 +9,30 @@ class Mustache
9
9
  #
10
10
  # You shouldn't use this class directly.
11
11
  class Template
12
+ # An UnclosedSection error is thrown when a {{# section }} is not
13
+ # closed.
14
+ #
15
+ # For example:
16
+ # {{# open }} blah {{/ close }}
17
+ class UnclosedSection < RuntimeError
18
+ attr_reader :message
19
+
20
+ # Report the line number of the offending unclosed section.
21
+ def initialize(source, matching_line, unclosed_section)
22
+ num = 0
23
+
24
+ source.split("\n").each_with_index do |line, i|
25
+ num = i + 1
26
+ break if line.strip == matching_line.strip
27
+ end
28
+
29
+ @message = "line #{num}: ##{unclosed_section.strip} is not closed"
30
+ end
31
+ end
32
+
12
33
  # Expects a Mustache template as a string along with a template
13
34
  # path, which it uses to find partials.
14
- def initialize(source, template_path = '.', template_extension = 'html')
35
+ def initialize(source, template_path = '.', template_extension = 'mustache')
15
36
  @source = source
16
37
  @template_path = template_path
17
38
  @template_extension = template_extension
@@ -85,9 +106,13 @@ class Mustache
85
106
  # 4. Partial tags - {{< partial_name }}
86
107
  def compile_tags(src)
87
108
  res = ""
88
- while src =~ /#{otag}(=|!|<|\{)?(.+?)\1?#{ctag}+/
109
+ while src =~ /#{otag}(#|=|!|<|\{)?(.+?)\1?#{ctag}+/
89
110
  res << str($`)
90
111
  case $1
112
+ when '#'
113
+ # Unclosed section - raise an error and
114
+ # report the line number
115
+ raise UnclosedSection.new(@source, $&, $2)
91
116
  when '!'
92
117
  # ignore comments
93
118
  when '='
@@ -1,3 +1,3 @@
1
1
  class Mustache
2
- Version = '0.3.2'
2
+ Version = '0.4.0'
3
3
  end
@@ -0,0 +1,81 @@
1
+ module Rack
2
+ module Bug
3
+ # MustachePanel is a Rack::Bug panel which tracks the time spent rendering
4
+ # Mustache views as well as all the variables accessed during view
5
+ # rendering.
6
+ #
7
+ # It can be used to track down slow partials and ensure you're only
8
+ # generating data you need.
9
+ #
10
+ # Also, it's fun.
11
+ class MustachePanel < Panel
12
+ require "rack/bug/panels/mustache_panel/mustache_extension"
13
+
14
+ # The view is responsible for rendering our panel. While Rack::Bug
15
+ # takes care of the nav, the content rendered by View is used for
16
+ # the panel itself.
17
+ class View < Mustache
18
+ self.path = ::File.dirname(__FILE__) + '/mustache_panel'
19
+
20
+ # We track the render times of all the Mustache views on this
21
+ # page load.
22
+ def times
23
+ MustachePanel.times.map do |key, value|
24
+ { :key => key, :value => value }
25
+ end
26
+ end
27
+
28
+ # Any variables used in this page load are collected and displayed.
29
+ def variables
30
+ vars = MustachePanel.variables.sort_by { |key, _| key.to_s }
31
+ vars.map do |key, value|
32
+ # Arrays can get too huge. Just show the first 10 to give you
33
+ # some idea.
34
+ if value.is_a?(Array) && value.size > 10
35
+ size = value.size
36
+ value = value.first(10)
37
+ value << "...and #{size - 10} more"
38
+ end
39
+
40
+ { :key => key, :value => value.inspect }
41
+ end
42
+ end
43
+ end
44
+
45
+ # Clear out our page load-specific variables.
46
+ def self.reset
47
+ Thread.current["rack.bug.mustache.times"] = {}
48
+ Thread.current["rack.bug.mustache.vars"] = {}
49
+ end
50
+
51
+ # The view render times for this page load
52
+ def self.times
53
+ Thread.current["rack.bug.mustache.times"] ||= {}
54
+ end
55
+
56
+ # The variables used on this page load
57
+ def self.variables
58
+ Thread.current["rack.bug.mustache.vars"] ||= {}
59
+ end
60
+
61
+ # The name of this Rack::Bug panel
62
+ def name
63
+ "mustache"
64
+ end
65
+
66
+ # The string used for our tab in Rack::Bug's navigation bar
67
+ def heading
68
+ "{{%.2fms}}" % self.class.times.values.inject(0.0) do |sum, obj|
69
+ sum + obj
70
+ end
71
+ end
72
+
73
+ # The content of our Rack::Bug panel
74
+ def content
75
+ View.render
76
+ ensure
77
+ self.class.reset
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,25 @@
1
+ if defined? Mustache
2
+ Mustache.class_eval do
3
+ alias_method :real_render, :render
4
+
5
+ def render(*args, &block)
6
+ out = ''
7
+ Rack::Bug::MustachePanel.times[self.class.name] = Benchmark.realtime do
8
+ out = real_render(*args, &block)
9
+ end
10
+ out
11
+ end
12
+
13
+ alias_method :to_html, :render
14
+ alias_method :to_text, :render
15
+ end
16
+
17
+ Mustache::Context.class_eval do
18
+ alias_method :real_get, :[]
19
+
20
+ def [](name)
21
+ return real_get(name) if name == :yield || !@mustache.respond_to?(name)
22
+ Rack::Bug::MustachePanel.variables[name] = real_get(name)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ <h3>Render Times</h3>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>View</th>
6
+ <th>Render Time</th>
7
+ </tr>
8
+
9
+ {{# times }}
10
+ <tr>
11
+ <td>{{ key }}</td>
12
+ <td>{{ value }}</td>
13
+ </tr>
14
+ {{/ times }}
15
+ </table>
16
+
17
+ <h3>Variables</h3>
18
+
19
+ <table>
20
+ <tr>
21
+ <th>Name</th>
22
+ <th>Value</th>
23
+ </tr>
24
+
25
+ {{# variables }}
26
+ <tr>
27
+ <td>{{ key }}</td>
28
+ <td>{{ value }}</td>
29
+ </tr>
30
+ {{/ variables }}
31
+ </table>
32
+
@@ -0,0 +1,38 @@
1
+ require 'test/unit'
2
+
3
+ module TestViews; end
4
+
5
+ class AutoloadingTest < Test::Unit::TestCase
6
+ def setup
7
+ Mustache.view_path = File.dirname(__FILE__) + '/../examples'
8
+ end
9
+
10
+ def test_autoload
11
+ klass = Mustache.view_class(:Comments)
12
+ assert_equal Comments, klass
13
+ end
14
+
15
+ def test_autoload_lowercase
16
+ klass = Mustache.view_class(:comments)
17
+ assert_equal Comments, klass
18
+ end
19
+
20
+ def test_autoload_nil
21
+ klass = Mustache.view_class(nil)
22
+ assert_equal Mustache, klass
23
+ end
24
+
25
+ def test_autoload_empty_string
26
+ klass = Mustache.view_class('')
27
+ assert_equal Mustache, klass
28
+ end
29
+
30
+ def test_namespaced_autoload
31
+ Mustache.view_namespace = TestViews
32
+ klass = Mustache.view_class('Namespaced')
33
+ assert_equal TestViews::Namespaced, klass
34
+ assert_equal <<-end_render.strip, klass.render
35
+ <h1>Dragon &lt; Tiger</h1>
36
+ end_render
37
+ end
38
+ end
@@ -224,6 +224,29 @@ data
224
224
  end
225
225
  end
226
226
 
227
+ def test_reports_unclosed_sections
228
+ instance = Mustache.new
229
+ instance[:list] = [ :item => 1234 ]
230
+ instance.template = '{{#list}} <li>{{item}}</li> {{/gist}}'
231
+
232
+ assert_raise Mustache::Template::UnclosedSection do
233
+ instance.render
234
+ end
235
+ end
236
+
237
+ def test_unclosed_sections_reports_the_line_number
238
+ instance = Mustache.new
239
+ instance[:list] = [ :item => 1234 ]
240
+ instance.template = "hi\nmom\n{{#list}} <li>{{item}}</li> {{/gist}}"
241
+
242
+ begin
243
+ instance.render
244
+ rescue => e
245
+ end
246
+
247
+ assert e.message.include?('line 3')
248
+ end
249
+
227
250
  def test_enumerable_sections_accept_a_hash_as_a_context
228
251
  instance = Mustache.new
229
252
  instance[:list] = { :item => 1234 }
@@ -240,6 +263,31 @@ data
240
263
  assert_equal '<li>1234</li>', instance.render.strip
241
264
  end
242
265
 
266
+ def test_not_found_in_context_renders_empty_string
267
+ instance = Mustache.new
268
+ instance.template = '{{#list}} <li>{{item}}</li> {{/list}}'
269
+
270
+ assert_equal '', instance.render.strip
271
+ end
272
+
273
+ def test_not_found_in_nested_context_renders_empty_string
274
+ instance = Mustache.new
275
+ instance[:list] = { :item => 1234 }
276
+ instance.template = '{{#list}} <li>{{prefix}}{{item}}</li> {{/list}}'
277
+
278
+ assert_equal '<li>1234</li>', instance.render.strip
279
+ end
280
+
281
+ def test_not_found_in_context_raises_when_asked_to
282
+ instance = Mustache.new
283
+ instance.raise_on_context_miss = true
284
+ instance.template = '{{#list}} <li>{{item}}</li> {{/list}}'
285
+
286
+ assert_raises Mustache::ContextMiss do
287
+ instance.render.strip
288
+ end
289
+ end
290
+
243
291
  def test_knows_when_its_been_compiled_when_set_with_string
244
292
  klass = Class.new(Mustache)
245
293
 
@@ -250,7 +298,7 @@ data
250
298
 
251
299
  def test_knows_when_its_been_compiled_when_using_a_file_template
252
300
  klass = Class.new(Simple)
253
- klass.template_file = File.dirname(__FILE__) + '/../examples/simple.html'
301
+ klass.template_file = File.dirname(__FILE__) + '/../examples/simple.mustache'
254
302
 
255
303
  assert ! klass.compiled?
256
304
  klass.render
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mustache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wanstrath
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-19 00:00:00 -07:00
12
+ date: 2009-10-27 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -36,34 +36,40 @@ files:
36
36
  - benchmarks/simple.erb
37
37
  - benchmarks/speed.rb
38
38
  - contrib/mustache.vim
39
- - examples/comments.html
39
+ - examples/comments.mustache
40
40
  - examples/comments.rb
41
- - examples/complex_view.html
41
+ - examples/complex_view.mustache
42
42
  - examples/complex_view.rb
43
- - examples/delimiters.html
43
+ - examples/delimiters.mustache
44
44
  - examples/delimiters.rb
45
- - examples/double_section.html
45
+ - examples/double_section.mustache
46
46
  - examples/double_section.rb
47
- - examples/escaped.html
47
+ - examples/escaped.mustache
48
48
  - examples/escaped.rb
49
- - examples/inner_partial.html
49
+ - examples/inner_partial.mustache
50
50
  - examples/inner_partial.txt
51
+ - examples/namespaced.mustache
52
+ - examples/namespaced.rb
51
53
  - examples/passenger.conf
52
54
  - examples/passenger.rb
53
- - examples/simple.html
55
+ - examples/simple.mustache
54
56
  - examples/simple.rb
55
- - examples/template_partial.html
57
+ - examples/template_partial.mustache
56
58
  - examples/template_partial.rb
57
59
  - examples/template_partial.txt
58
- - examples/unescaped.html
60
+ - examples/unescaped.mustache
59
61
  - examples/unescaped.rb
60
- - examples/view_partial.html
62
+ - examples/view_partial.mustache
61
63
  - examples/view_partial.rb
62
64
  - lib/mustache.rb
63
65
  - lib/mustache/context.rb
64
66
  - lib/mustache/sinatra.rb
65
67
  - lib/mustache/template.rb
66
68
  - lib/mustache/version.rb
69
+ - lib/rack/bug/panels/mustache_panel.rb
70
+ - lib/rack/bug/panels/mustache_panel/mustache_extension.rb
71
+ - lib/rack/bug/panels/mustache_panel/view.mustache
72
+ - test/autoloading_test.rb
67
73
  - test/mustache_test.rb
68
74
  has_rdoc: true
69
75
  homepage: http://github.com/defunkt/mustache
@@ -94,12 +100,14 @@ signing_key:
94
100
  specification_version: 3
95
101
  summary: Mustache is a framework-agnostic way to render logic-free views.
96
102
  test_files:
103
+ - test/autoloading_test.rb
97
104
  - test/mustache_test.rb
98
105
  - examples/comments.rb
99
106
  - examples/complex_view.rb
100
107
  - examples/delimiters.rb
101
108
  - examples/double_section.rb
102
109
  - examples/escaped.rb
110
+ - examples/namespaced.rb
103
111
  - examples/passenger.rb
104
112
  - examples/simple.rb
105
113
  - examples/template_partial.rb