mustache 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.kick ADDED
@@ -0,0 +1,26 @@
1
+ # take control of the growl notifications
2
+ module GrowlHacks
3
+ def growl(type, subject, body, *args, &block)
4
+ case type
5
+ when Kicker::GROWL_NOTIFICATIONS[:succeeded]
6
+ puts subject = "Success"
7
+ body = body.split("\n").last
8
+ when Kicker::GROWL_NOTIFICATIONS[:failed]
9
+ subject = "Failure"
10
+ puts body
11
+ body = body.split("\n").last
12
+ else
13
+ return nil
14
+ end
15
+ super(type, subject, body, *args, &block)
16
+ end
17
+ end
18
+
19
+ Kicker.send :extend, GrowlHacks
20
+
21
+ # no logging
22
+ Kicker::Utils.module_eval do
23
+ def log(message)
24
+ nil
25
+ end
26
+ end
data/README.md CHANGED
@@ -1,10 +1,8 @@
1
1
  Mustache
2
2
  =========
3
3
 
4
- Inspired by [ctemplate](http://code.google.com/p/google-ctemplate/)
5
- and
6
- [et](http://www.ivan.fomichev.name/2008/05/erlang-template-engine-prototype.html),
7
- Mustache is a framework-agnostic way to render logic-free views.
4
+ Inspired by [ctemplate][1] and [et][2], Mustache is a
5
+ framework-agnostic way to render logic-free views.
8
6
 
9
7
  As ctemplates says, "It emphasizes separating logic from presentation:
10
8
  it is impossible to embed application logic in this template language."
@@ -82,7 +80,7 @@ Now let's write the template:
82
80
  This template references our view methods. To bring it all together,
83
81
  here's the code to render actual HTML;
84
82
 
85
- Simple.new.to_html
83
+ Simple.render
86
84
 
87
85
  Which returns the following:
88
86
 
@@ -184,7 +182,7 @@ We can fill in the values at will:
184
182
  dict = Dict.new
185
183
  dict[:name] = 'George'
186
184
  dict[:value] = 100
187
- dict.to_html
185
+ dict.render
188
186
 
189
187
  Which returns:
190
188
 
@@ -194,7 +192,7 @@ Which returns:
194
192
  We can re-use the same object, too:
195
193
 
196
194
  dict[:name] = 'Tony'
197
- dict.to_html
195
+ dict.render
198
196
  Hello Tony
199
197
  You have just won $100!
200
198
 
@@ -299,7 +297,7 @@ normal class.
299
297
 
300
298
  Now:
301
299
 
302
- Simple.new(request.ssl?).to_html
300
+ Simple.new(request.ssl?).render
303
301
 
304
302
  Convoluted but you get the idea.
305
303
 
@@ -312,6 +310,9 @@ Mustache ships with Sinatra integration. Please see
312
310
  <http://defunkt.github.com/mustache/classes/Mustache/Sinatra.html> for
313
311
  complete documentation.
314
312
 
313
+ An example Sinatra application is also provided:
314
+ <http://github.com/defunkt/mustache-sinatra-example>
315
+
315
316
 
316
317
  Installation
317
318
  ------------
@@ -343,3 +344,6 @@ Meta
343
344
  * Test: <http://runcoderun.com/defunkt/mustache>
344
345
  * Gems: <http://gemcutter.org/gems/mustache>
345
346
  * Boss: Chris Wanstrath :: <http://github.com/defunkt>
347
+
348
+ [1]: http://code.google.com/p/google-ctemplate/
349
+ [2]: http://www.ivan.fomichev.name/2008/05/erlang-template-engine-prototype.html
data/Rakefile CHANGED
@@ -9,6 +9,12 @@ Rake::TestTask.new do |t|
9
9
  t.verbose = false
10
10
  end
11
11
 
12
+ desc "Launch Kicker (like autotest)"
13
+ task :kicker do
14
+ puts "Kicking... (ctrl+c to cancel)"
15
+ exec "kicker -e rake test lib"
16
+ end
17
+
12
18
  begin
13
19
  require 'jeweler'
14
20
  $LOAD_PATH.unshift 'lib'
@@ -23,7 +29,8 @@ begin
23
29
  gemspec.version = Mustache::Version
24
30
  end
25
31
  rescue LoadError
26
- puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
32
+ puts "Jeweler not available."
33
+ puts "Install it with: gem install jeweler"
27
34
  end
28
35
 
29
36
  begin
@@ -34,6 +41,9 @@ end
34
41
 
35
42
  desc "Push a new version to Gemcutter"
36
43
  task :publish => [ :gemspec, :build ] do
37
- system "gem push pkg/mustache-#{Mustache::Version}.gem"
38
- exec "git clean -fd"
44
+ system "git tag v#{Mustache::Version}"
45
+ system "git push origin v#{Mustache::Version}"
46
+ system "gem push pkg/mustache-#{Mustache::Version}.gem"
47
+ system "git clean -fd"
48
+ exec "rake pages"
39
49
  end
data/benchmarks/speed.rb CHANGED
@@ -41,9 +41,11 @@ end
41
41
 
42
42
  content = File.read(ComplexView.template_file)
43
43
 
44
- bench '{ w/o caching' do
45
- tpl = ComplexView.new
46
- tpl.template = content
47
- tpl[:item] = items
48
- tpl.to_html
44
+ unless ENV['CACHED']
45
+ bench '{ w/o caching' do
46
+ tpl = ComplexView.new
47
+ tpl.template = content
48
+ tpl[:item] = items
49
+ tpl.to_html
50
+ end
49
51
  end
@@ -0,0 +1 @@
1
+ ## Again, {{title}}! ##
@@ -7,6 +7,10 @@ class TemplatePartial < Mustache
7
7
  def title
8
8
  "Welcome"
9
9
  end
10
+
11
+ def title_bars
12
+ '-' * title.size
13
+ end
10
14
  end
11
15
 
12
16
  if $0 == __FILE__
@@ -0,0 +1,4 @@
1
+ {{title}}
2
+ {{title_bars}}
3
+
4
+ {{<inner_partial}}
data/lib/mustache.rb CHANGED
@@ -1,172 +1,126 @@
1
- require 'cgi'
2
-
1
+ require 'mustache/template'
2
+ require 'mustache/context'
3
+
4
+ # Mustache is the base class from which your Mustache subclasses
5
+ # should inherit (though it can be used on its own).
6
+ #
7
+ # The typical Mustache workflow is as follows:
8
+ #
9
+ # * Create a Mustache subclass: class Stats < Mustache
10
+ # * Create a template: stats.html
11
+ # * Instantiate an instance: view = Stats.new
12
+ # * Render that instance: view.render
13
+ #
14
+ # You can skip the instantiation by calling `Stats.render` directly.
15
+ #
16
+ # While Mustache will do its best to load and render a template for
17
+ # you, this process is completely customizable using a few options.
18
+ #
19
+ # All settings can be overriden at either the class or instance
20
+ # level. For example, going with the above example, we can do either
21
+ # `Stats.template_path = "/usr/local/templates"` or
22
+ # `view.template_path = "/usr/local/templates"`
23
+ #
24
+ # Here are the available options:
25
+ #
26
+ # * template_path
27
+ #
28
+ # The `template_path` setting determines the path Mustache uses when
29
+ # looking for a template. By default it is "."
30
+ # Setting it to /usr/local/templates, for example, means (given all
31
+ # other settings are default) a Mustache subclass `Stats` will try to
32
+ # load /usr/local/templates/stats.html
33
+ #
34
+ # * template_extension
35
+ #
36
+ # The `template_extension` is the extension Mustache uses when looking
37
+ # for template files. By default it is "html"
38
+ #
39
+ # * template_file
40
+ #
41
+ # You can tell Mustache exactly which template to us with this
42
+ # setting. It can be a relative or absolute path.
43
+ #
44
+ # * template
45
+ #
46
+ # Sometimes you want Mustache to render a string, not a file. In those
47
+ # cases you may set the `template` setting. For example:
48
+ #
49
+ # >> Mustache.render("Hello {{planet}}", :planet => "World!")
50
+ # => "Hello World!"
51
+ #
3
52
  class Mustache
4
- # A Template is a compiled version of a Mustache template.
5
- class Template
6
- def initialize(source, template_path)
7
- @source = source
8
- @template_path = template_path
9
- @tmpid = 0
10
- end
11
-
12
- def render(context)
13
- class << self; self; end.class_eval <<-EOF, __FILE__, __LINE__ - 1
14
- def render(ctx)
15
- #{compile}
16
- end
17
- EOF
18
- render(context)
19
- end
20
-
21
- def compile(src = @source)
22
- "\"#{compile_sections(src)}\""
23
- end
24
-
25
- ## private
26
-
27
- # {{#sections}}okay{{/sections}}
28
- #
29
- # Sections can return true, false, or an enumerable.
30
- # If true, the section is displayed.
31
- # If false, the section is not displayed.
32
- # If enumerable, the return value is iterated over (a for loop).
33
- def compile_sections(src)
34
- res = ""
35
- while src =~ /^\s*\{\{\#(.+)\}\}\n*(.+)^\s*\{\{\/\1\}\}\n*/m
36
- res << compile_tags($`)
37
- name = $1.strip.to_sym.inspect
38
- code = compile($2)
39
- ctxtmp = "ctx#{tmpid}"
40
- res << ev("(v = ctx[#{name}]) ? v.respond_to?(:each) ? "\
41
- "(#{ctxtmp}=ctx.dup; r=v.map{|h|ctx.merge!(h);#{code}}.join; "\
42
- "ctx.replace(#{ctxtmp});r) : #{code} : ''")
43
- src = $'
44
- end
45
- res << compile_tags(src)
46
- end
47
-
48
- # Find and replace all non-section tags.
49
- # In particular we look for four types of tags:
50
- # 1. Escaped variable tags - {{var}}
51
- # 2. Unescaped variable tags - {{{var}}}
52
- # 3. Comment variable tags - {{! comment}
53
- # 4. Partial tags - {{< partial_name }}
54
- def compile_tags(src)
55
- res = ""
56
- while src =~ /\{\{(!|<|\{)?([^\/#]+?)\1?\}\}+/
57
- res << str($`)
58
- case $1
59
- when '!'
60
- # ignore comments
61
- when '<'
62
- res << compile_partial($2.strip)
63
- when '{'
64
- res << utag($2.strip)
65
- else
66
- res << etag($2.strip)
67
- end
68
- src = $'
69
- end
70
- res << str(src)
71
- end
72
-
73
- # Partials are basically a way to render views from inside other views.
74
- def compile_partial(name)
75
- klass = Mustache.classify(name)
76
- if Object.const_defined?(klass)
77
- ev("#{klass}.render")
78
- else
79
- src = File.read(@template_path + '/' + name + '.html')
80
- compile(src)[1..-2]
81
- end
82
- end
83
-
84
- # Generate a temporary id.
85
- def tmpid
86
- @tmpid += 1
87
- end
88
-
89
- def str(s)
90
- s.inspect[1..-2]
91
- end
92
-
93
- def etag(s)
94
- ev("Mustache.escape(ctx[#{s.strip.to_sym.inspect}])")
95
- end
96
-
97
- def utag(s)
98
- ev("ctx[#{s.strip.to_sym.inspect}]")
99
- end
53
+ # Helper method for quickly instantiating and rendering a view.
54
+ def self.render(*args)
55
+ new.render(*args)
56
+ end
100
57
 
101
- def ev(s)
102
- "#\{#{s}}"
103
- end
58
+ # Alias for `render`
59
+ def self.to_html(*args)
60
+ render(*args)
104
61
  end
105
62
 
106
- class Context < Hash
107
- def initialize(mustache)
108
- @mustache = mustache
109
- super()
110
- end
63
+ # Alias for `render`
64
+ def self.to_text(*args)
65
+ render(*args)
66
+ end
111
67
 
112
- def [](name)
113
- if has_key?(name)
114
- super
115
- elsif @mustache.respond_to?(name)
116
- @mustache.send(name)
117
- else
118
- raise "Can't find #{name} in #{inspect}"
119
- end
120
- end
68
+ # The template path informs your Mustache subclass where to look for its
69
+ # corresponding template. By default it's the current directory (".")
70
+ def self.template_path
71
+ @template_path || '.'
121
72
  end
122
73
 
123
- # Helper method for quickly instantiating and rendering a view.
124
- def self.render(*args)
125
- new.render(*args)
74
+ def self.template_path=(path)
75
+ @template_path = File.expand_path(path)
126
76
  end
127
77
 
128
- class << self
129
- alias_method :to_html, :render
130
- alias_method :to_text, :render
78
+ # Alias for `template_path`
79
+ def self.path
80
+ template_path
131
81
  end
132
82
 
133
- # The path informs your Mustache subclass where to look for its
134
- # corresponding template.
83
+ # Alias for `template_path`
135
84
  def self.path=(path)
136
- @path = File.expand_path(path)
85
+ self.template_path = path
137
86
  end
138
87
 
139
- def self.path
140
- @path || '.'
88
+ # A Mustache template's default extension is 'html'
89
+ def self.template_extension
90
+ @template_extension || 'html'
141
91
  end
142
92
 
143
- # Templates are self.class.name.underscore + extension -- a class of
144
- # Dashboard would have a template (relative to the path) of
145
- # dashboard.html
93
+ def self.template_extension=(template_extension)
94
+ @template_extension = template_extension
95
+ end
96
+
97
+ # The template file is the absolute path of the file Mustache will
98
+ # use as its template. By default it's ./class_name.html
146
99
  def self.template_file
147
- @template_file ||= path + '/' + underscore(to_s) + '.' + template_extension
100
+ @template_file || "#{template_path}/#{underscore(to_s)}.#{template_extension}"
148
101
  end
149
102
 
150
103
  def self.template_file=(template_file)
151
104
  @template_file = template_file
152
105
  end
153
106
 
107
+ # The template is the actual string Mustache uses as its template.
108
+ # There is a bit of magic here: what we get back is actually a
109
+ # Mustache::Template object here, but you can still safely use
110
+ # `template=` with a string.
154
111
  def self.template
155
- @template ||= templateify(File.read(template_file))
112
+ @template || templateify(File.read(template_file))
156
113
  end
157
114
 
158
- # Default extension is 'html'
159
- def self.template_extension
160
- @template_extension ||= 'html'
161
- end
162
-
163
- def self.template_extension=(template_extension)
164
- @template_extension = template_extension
115
+ def self.template=(template)
116
+ @template = templateify(template)
165
117
  end
166
118
 
167
119
  # template_partial => TemplatePartial
168
120
  def self.classify(underscored)
169
- underscored.split(/[-_]/).map { |part| part[0] = part[0].chr.upcase; part }.join
121
+ underscored.split(/[-_]/).map do |part|
122
+ part[0] = part[0].chr.upcase; part
123
+ end.join
170
124
  end
171
125
 
172
126
  # TemplatePartial => template_partial
@@ -176,31 +130,60 @@ class Mustache
176
130
  string.gsub(/[A-Z]/) { |s| "_#{s.downcase}"}
177
131
  end
178
132
 
179
- # Escape HTML.
180
- def self.escape(string)
181
- CGI.escapeHTML(string.to_s)
133
+ # Turns a string into a Mustache::Template. If passed a Template,
134
+ # returns it.
135
+ def self.templateify(obj)
136
+ if obj.is_a?(Template)
137
+ obj
138
+ else
139
+ Template.new(obj.to_s, template_path, template_extension)
140
+ end
182
141
  end
183
142
 
184
- def self.templateify(obj)
185
- obj.is_a?(Template) ? obj : Template.new(obj.to_s, path)
143
+ # Instance version.Turns a string into a Mustache::Template. If passed a Template,
144
+ def templateify(obj)
145
+ if obj.is_a?(Template)
146
+ obj
147
+ else
148
+ Template.new(obj.to_s, template_path, template_extension)
149
+ end
186
150
  end
187
151
 
188
- # The template itself. You can override this if you'd like.
189
- def template
190
- @template ||= self.class.template
152
+ #
153
+ # Instance level settings
154
+ #
155
+
156
+ def template_path
157
+ @template_path || self.class.template_path
191
158
  end
192
159
 
193
- def template=(template)
194
- @template = self.class.templateify(template)
160
+ def template_path=(template_path)
161
+ @template_path = template_path
195
162
  end
196
163
 
197
- # Pass a block to `debug` with your debug putses. Set the `DEBUG`
198
- # env variable when you want to run those blocks.
199
- #
200
- # e.g.
201
- # debug { puts @context.inspect }
202
- def debug
203
- yield if ENV['DEBUG']
164
+ def template_extension
165
+ @template_extension || self.class.template_extension
166
+ end
167
+
168
+ def template_extension=(template_extension)
169
+ @template_extension = template_extension
170
+ end
171
+
172
+ def template_file
173
+ return @template_file if @template_file
174
+ "#{template_path}/#{Mustache.underscore(self.class.name)}.#{template_extension}"
175
+ end
176
+
177
+ def template_file=(template_file)
178
+ @template_file = template_file
179
+ end
180
+
181
+ def template
182
+ @template || templateify(File.read(template_file))
183
+ end
184
+
185
+ def template=(template)
186
+ @template = templateify(template)
204
187
  end
205
188
 
206
189
  # A helper method which gives access to the context at a given time.
@@ -210,7 +193,12 @@ class Mustache
210
193
  @context ||= Context.new(self)
211
194
  end
212
195
 
213
- # Context accessors
196
+ # Context accessors.
197
+ #
198
+ # view = Mustache.new
199
+ # view[:name] = "Jon"
200
+ # view.template = "Hi, {{name}}!"
201
+ # view.render # => "Hi, Jon!"
214
202
  def [](key)
215
203
  context[key.to_sym]
216
204
  end
@@ -222,7 +210,7 @@ class Mustache
222
210
  # Parses our fancy pants template file and returns normal file with
223
211
  # all special {{tags}} and {{#sections}}replaced{{/sections}}.
224
212
  def render(data = template, ctx = {})
225
- self.class.templateify(data).render(context.update(ctx))
213
+ templateify(data).render(context.update(ctx))
226
214
  end
227
215
  alias_method :to_html, :render
228
216
  alias_method :to_text, :render
@@ -0,0 +1,20 @@
1
+ class Mustache
2
+ # A Context represents the context which a Mustache template is
3
+ # executed within. All Mustache tags reference keys in the Context.
4
+ class Context < Hash
5
+ def initialize(mustache)
6
+ @mustache = mustache
7
+ super()
8
+ end
9
+
10
+ def [](name)
11
+ if has_key?(name)
12
+ super
13
+ elsif @mustache.respond_to?(name)
14
+ @mustache.send(name)
15
+ else
16
+ raise "Can't find #{name} in #{@mustache.inspect}"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,127 @@
1
+ require 'cgi'
2
+
3
+ class Mustache
4
+ # A Template is a compiled version of a Mustache template.
5
+ #
6
+ # The idea is this: when handed a Mustache template, convert it into
7
+ # a Ruby string by transforming Mustache tags into interpolated
8
+ # Ruby.
9
+ #
10
+ # You shouldn't use this class directly.
11
+ class Template
12
+ # Expects a Mustache template as a string along with a template
13
+ # path, which it uses to find partials.
14
+ def initialize(source, template_path = '.', template_extension = 'html')
15
+ @source = source
16
+ @template_path = template_path
17
+ @template_extension = template_extension
18
+ @tmpid = 0
19
+ end
20
+
21
+ # Renders the `@source` Mustache template using the given
22
+ # `context`, which should be a simple hash keyed with symbols.
23
+ def render(context)
24
+ # Compile our Mustache template into a Ruby string
25
+ compiled = "def render(ctx) #{compile} end"
26
+
27
+ # Here we rewrite ourself with the interpolated Ruby version of
28
+ # our Mustache template so subsequent calls are very fast and
29
+ # can skip the compilation stage.
30
+ instance_eval(compiled, __FILE__, __LINE__ - 1)
31
+
32
+ # Call the newly rewritten version of #render
33
+ render(context)
34
+ end
35
+
36
+ # Does the dirty work of transforming a Mustache template into an
37
+ # interpolation-friendly Ruby string.
38
+ def compile(src = @source)
39
+ "\"#{compile_sections(src)}\""
40
+ end
41
+
42
+ # {{#sections}}okay{{/sections}}
43
+ #
44
+ # Sections can return true, false, or an enumerable.
45
+ # If true, the section is displayed.
46
+ # If false, the section is not displayed.
47
+ # If enumerable, the return value is iterated over (a `for` loop).
48
+ def compile_sections(src)
49
+ res = ""
50
+ while src =~ /^\s*\{\{\#(.+)\}\}\n*(.+)^\s*\{\{\/\1\}\}\n*/m
51
+ # $` = The string to the left of the last successful match
52
+ res << compile_tags($`)
53
+ name = $1.strip.to_sym.inspect
54
+ code = compile($2)
55
+ ctxtmp = "ctx#{tmpid}"
56
+ res << ev("(v = ctx[#{name}]) ? v.respond_to?(:each) ? "\
57
+ "(#{ctxtmp}=ctx.dup; r=v.map{|h|ctx.update(h);#{code}}.join; "\
58
+ "ctx.replace(#{ctxtmp});r) : #{code} : ''")
59
+ # $' = The string to the right of the last successful match
60
+ src = $'
61
+ end
62
+ res << compile_tags(src)
63
+ end
64
+
65
+ # Find and replace all non-section tags.
66
+ # In particular we look for four types of tags:
67
+ # 1. Escaped variable tags - {{var}}
68
+ # 2. Unescaped variable tags - {{{var}}}
69
+ # 3. Comment variable tags - {{! comment}
70
+ # 4. Partial tags - {{< partial_name }}
71
+ def compile_tags(src)
72
+ res = ""
73
+ while src =~ /\{\{(!|<|\{)?([^\/#]+?)\1?\}\}+/
74
+ res << str($`)
75
+ case $1
76
+ when '!'
77
+ # ignore comments
78
+ when '<'
79
+ res << compile_partial($2.strip)
80
+ when '{'
81
+ res << utag($2.strip)
82
+ else
83
+ res << etag($2.strip)
84
+ end
85
+ src = $'
86
+ end
87
+ res << str(src)
88
+ end
89
+
90
+ # Partials are basically a way to render views from inside other views.
91
+ def compile_partial(name)
92
+ klass = Mustache.classify(name)
93
+ if Object.const_defined?(klass)
94
+ ev("#{klass}.render")
95
+ else
96
+ src = File.read("#{@template_path}/#{name}.#{@template_extension}")
97
+ compile(src)[1..-2]
98
+ end
99
+ end
100
+
101
+ # Generate a temporary id, used when compiling code.
102
+ def tmpid
103
+ @tmpid += 1
104
+ end
105
+
106
+ # Get a (hopefully) literal version of an object, sans quotes
107
+ def str(s)
108
+ s.inspect[1..-2]
109
+ end
110
+
111
+ # {{}} - an escaped tag
112
+ def etag(s)
113
+ ev("CGI.escapeHTML(ctx[#{s.strip.to_sym.inspect}].to_s)")
114
+ end
115
+
116
+ # {{{}}} - an unescaped tag
117
+ def utag(s)
118
+ ev("ctx[#{s.strip.to_sym.inspect}]")
119
+ end
120
+
121
+ # An interpolation-friendly version of a string, for use within a
122
+ # Ruby string.
123
+ def ev(s)
124
+ "#\{#{s}}"
125
+ end
126
+ end
127
+ end
@@ -1,3 +1,3 @@
1
1
  class Mustache
2
- Version = '0.1.4'
2
+ Version = '0.2.0'
3
3
  end
@@ -23,7 +23,7 @@ end_passenger
23
23
  end
24
24
 
25
25
  def test_complex_view
26
- assert_equal <<-end_complex, ComplexView.to_html
26
+ assert_equal <<-end_complex, ComplexView.render
27
27
  <h1>Colors</h1>
28
28
  <ul>
29
29
  <li><strong>red</strong></li>
@@ -34,7 +34,7 @@ end_complex
34
34
  end
35
35
 
36
36
  def test_simple
37
- assert_equal <<-end_simple, Simple.to_html
37
+ assert_equal <<-end_simple, Simple.render
38
38
  Hello Chris
39
39
  You have just won $10000!
40
40
  Well, $6000.0, after taxes.
@@ -47,7 +47,7 @@ end_simple
47
47
  view[:value] = '4000'
48
48
  view[:in_ca] = false
49
49
 
50
- assert_equal <<-end_simple, view.to_html
50
+ assert_equal <<-end_simple, view.render
51
51
  Hello Bob
52
52
  You have just won $4000!
53
53
  end_simple
@@ -62,7 +62,7 @@ end_simple
62
62
  { :taxed_value => 3 },
63
63
  ]
64
64
 
65
- assert_equal <<-end_simple, view.to_html
65
+ assert_equal <<-end_simple, view.render
66
66
  Hello Crazy
67
67
  You have just won $10000!
68
68
  Well, $1, after taxes.
@@ -76,11 +76,11 @@ end_simple
76
76
  view.template = 'Hi {{person}}!'
77
77
  view[:person] = 'mom'
78
78
 
79
- assert_equal 'Hi mom!', view.to_html
79
+ assert_equal 'Hi mom!', view.render
80
80
  end
81
81
 
82
82
  def test_view_partial
83
- assert_equal <<-end_partial.strip, ViewPartial.to_html
83
+ assert_equal <<-end_partial.strip, ViewPartial.render
84
84
  <h1>Welcome</h1>
85
85
  Hello Chris
86
86
  You have just won $10000!
@@ -91,22 +91,34 @@ end_partial
91
91
  end
92
92
 
93
93
  def test_template_partial
94
- assert_equal <<-end_partial.strip, TemplatePartial.to_html
94
+ assert_equal <<-end_partial.strip, TemplatePartial.render
95
95
  <h1>Welcome</h1>
96
96
  Again, Welcome!
97
97
  end_partial
98
98
  end
99
99
 
100
+ def test_template_partial_with_custom_extension
101
+ partial = TemplatePartial.new
102
+ partial.template_extension = 'txt'
103
+
104
+ assert_equal <<-end_partial.strip, partial.render.strip
105
+ Welcome
106
+ -------
107
+
108
+ ## Again, Welcome! ##
109
+ end_partial
110
+ end
111
+
100
112
  def test_comments
101
- assert_equal "<h1>A Comedy of Errors</h1>\n", Comments.to_html
113
+ assert_equal "<h1>A Comedy of Errors</h1>\n", Comments.render
102
114
  end
103
115
 
104
116
  def test_escaped
105
- assert_equal '<h1>Bear &gt; Shark</h1>', Escaped.to_html
117
+ assert_equal '<h1>Bear &gt; Shark</h1>', Escaped.render
106
118
  end
107
119
 
108
120
  def test_unescaped
109
- assert_equal '<h1>Bear > Shark</h1>', Unescaped.to_html
121
+ assert_equal '<h1>Bear > Shark</h1>', Unescaped.render
110
122
  end
111
123
 
112
124
  def test_classify
@@ -138,9 +150,9 @@ end_partial
138
150
  </VirtualHost>
139
151
  data
140
152
  template = File.read("examples/passenger.conf")
141
- assert_equal expected, Mustache.render(template, :stage => 'production',
142
- :server => 'example.com',
153
+ assert_equal expected, Mustache.render(template, :stage => 'production',
154
+ :server => 'example.com',
143
155
  :deploy_to => '/var/www/example.com' )
144
156
  end
145
157
 
146
- end
158
+ end
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.1.4
4
+ version: 0.2.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-08 00:00:00 -07:00
12
+ date: 2009-10-10 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -24,6 +24,7 @@ extra_rdoc_files:
24
24
  - README.md
25
25
  files:
26
26
  - .gitignore
27
+ - .kick
27
28
  - CONTRIBUTORS
28
29
  - LICENSE
29
30
  - README.md
@@ -39,18 +40,22 @@ files:
39
40
  - examples/escaped.html
40
41
  - examples/escaped.rb
41
42
  - examples/inner_partial.html
43
+ - examples/inner_partial.txt
42
44
  - examples/passenger.conf
43
45
  - examples/passenger.rb
44
46
  - examples/simple.html
45
47
  - examples/simple.rb
46
48
  - examples/template_partial.html
47
49
  - examples/template_partial.rb
50
+ - examples/template_partial.txt
48
51
  - examples/unescaped.html
49
52
  - examples/unescaped.rb
50
53
  - examples/view_partial.html
51
54
  - examples/view_partial.rb
52
55
  - lib/mustache.rb
56
+ - lib/mustache/context.rb
53
57
  - lib/mustache/sinatra.rb
58
+ - lib/mustache/template.rb
54
59
  - lib/mustache/version.rb
55
60
  - test/mustache_test.rb
56
61
  has_rdoc: true