mustache 0.13.0 → 0.98.0
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.md +2 -2
- data/Rakefile +1 -1
- data/lib/mustache/context.rb +7 -0
- data/lib/mustache/generator.rb +1 -1
- data/lib/mustache/parser.rb +13 -2
- data/lib/mustache/sinatra.rb +5 -0
- data/lib/mustache/version.rb +1 -1
- data/lib/mustache.rb +13 -0
- data/test/fixtures/dot_notation.mustache +6 -0
- data/test/fixtures/dot_notation.rb +25 -0
- data/test/mustache_test.rb +34 -0
- data/test/spec_test.rb +4 -4
- metadata +6 -4
data/README.md
CHANGED
@@ -61,7 +61,7 @@ We've got an `examples` folder but here's the canonical one:
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def taxed_value
|
64
|
-
value
|
64
|
+
value * 0.6
|
65
65
|
end
|
66
66
|
|
67
67
|
def in_ca
|
@@ -236,7 +236,7 @@ Then just include it:
|
|
236
236
|
end
|
237
237
|
|
238
238
|
def taxed_value
|
239
|
-
value
|
239
|
+
value * 0.6
|
240
240
|
end
|
241
241
|
|
242
242
|
def in_ca
|
data/Rakefile
CHANGED
data/lib/mustache/context.rb
CHANGED
@@ -42,6 +42,13 @@ class Mustache
|
|
42
42
|
@stack.detect { |frame| frame.is_a?(Mustache) }
|
43
43
|
end
|
44
44
|
|
45
|
+
# Allows customization of how Mustache escapes things.
|
46
|
+
#
|
47
|
+
# Returns a String.
|
48
|
+
def escapeHTML(str)
|
49
|
+
mustache_in_stack.escapeHTML(str)
|
50
|
+
end
|
51
|
+
|
45
52
|
# Adds a new object to the context's internal stack.
|
46
53
|
#
|
47
54
|
# Returns the Context.
|
data/lib/mustache/generator.rb
CHANGED
@@ -153,7 +153,7 @@ class Mustache
|
|
153
153
|
v = ctx[#{name.to_sym.inspect}]
|
154
154
|
v = Mustache::Template.new(v.call.to_s).render(ctx.dup) if v.is_a?(Proc)
|
155
155
|
ctx.frame[ctx.key] = v if ctx.frame.is_a?(Hash)
|
156
|
-
|
156
|
+
ctx.escapeHTML(v.to_s)
|
157
157
|
compiled
|
158
158
|
end
|
159
159
|
|
data/lib/mustache/parser.rb
CHANGED
@@ -50,7 +50,7 @@ EOF
|
|
50
50
|
SKIP_WHITESPACE = [ '#', '^', '/', '<', '>', '=', '!' ]
|
51
51
|
|
52
52
|
# The content allowed in a tag name.
|
53
|
-
ALLOWED_CONTENT = /(\w|[
|
53
|
+
ALLOWED_CONTENT = /(\w|[?!\/.-])*/
|
54
54
|
|
55
55
|
# These types of tags allow any content,
|
56
56
|
# the rest only allow ALLOWED_CONTENT.
|
@@ -174,7 +174,18 @@ EOF
|
|
174
174
|
type = "}" if type == "{"
|
175
175
|
@result << [:mustache, :utag, content]
|
176
176
|
else
|
177
|
-
|
177
|
+
parts = content.to_s.split(".").reverse
|
178
|
+
|
179
|
+
if parts.size == 0
|
180
|
+
# implicit iterators - {{.}}
|
181
|
+
@result << [:mustache, :etag, "to_s"]
|
182
|
+
else
|
183
|
+
# dot notation - {{person.name}}
|
184
|
+
etag = [:mustache, :etag, parts.shift]
|
185
|
+
@result << parts.inject(etag) { |section, key|
|
186
|
+
[:mustache, :section, key, section, content]
|
187
|
+
}
|
188
|
+
end
|
178
189
|
end
|
179
190
|
|
180
191
|
# Skip whitespace and any balancing sigils after the content
|
data/lib/mustache/sinatra.rb
CHANGED
@@ -88,6 +88,11 @@ class Mustache
|
|
88
88
|
# Copy instance variables set in Sinatra to the view
|
89
89
|
instance_variables.each do |name|
|
90
90
|
instance.instance_variable_set(name, instance_variable_get(name))
|
91
|
+
|
92
|
+
# Automagic attr_readers for ivars you set in Sinatra routes.
|
93
|
+
if !instance.respond_to?(name)
|
94
|
+
(class << instance; self end).send(:attr_reader, name.to_s.sub('@',''))
|
95
|
+
end
|
91
96
|
end
|
92
97
|
|
93
98
|
# Render with locals.
|
data/lib/mustache/version.rb
CHANGED
data/lib/mustache.rb
CHANGED
@@ -315,6 +315,19 @@ class Mustache
|
|
315
315
|
@template = templateify(template)
|
316
316
|
end
|
317
317
|
|
318
|
+
# Override this to provide custom escaping.
|
319
|
+
#
|
320
|
+
# class PersonView < Mustache
|
321
|
+
# def escapeHTML(str)
|
322
|
+
# my_html_escape_method(str)
|
323
|
+
# end
|
324
|
+
# end
|
325
|
+
#
|
326
|
+
# Returns a String
|
327
|
+
def escapeHTML(str)
|
328
|
+
CGI.escapeHTML(str)
|
329
|
+
end
|
330
|
+
|
318
331
|
# Instance level version of `Mustache.raise_on_context_miss?`
|
319
332
|
def raise_on_context_miss?
|
320
333
|
self.class.raise_on_context_miss? || @raise_on_context_miss
|
@@ -0,0 +1,6 @@
|
|
1
|
+
* {{person.name.first}} {{person.name.last}}
|
2
|
+
* {{person.age}}
|
3
|
+
* {{person.hometown.city}}, {{person.hometown.state}}
|
4
|
+
* {{#person}}{{hometown.city}}, {{hometown.state}}{{/person}}
|
5
|
+
* {{#person}}{{#hometown}}{{city}}, {{state}}{{/hometown}}{{/person}}
|
6
|
+
* {{normal}}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
require 'mustache'
|
3
|
+
|
4
|
+
class DotNotation < Mustache
|
5
|
+
self.path = File.dirname(__FILE__)
|
6
|
+
|
7
|
+
def person
|
8
|
+
return {
|
9
|
+
:name => OpenStruct.new(:first => 'Chris', :last => 'Firescythe'),
|
10
|
+
:age => 24,
|
11
|
+
:hometown => {
|
12
|
+
:city => "Cincinnati",
|
13
|
+
:state => "OH"
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def normal
|
19
|
+
"Normal"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
if $0 == __FILE__
|
24
|
+
puts DotNotation.to_html
|
25
|
+
end
|
data/test/mustache_test.rb
CHANGED
@@ -497,6 +497,40 @@ template
|
|
497
497
|
assert_equal 'Marvin is 25', view.render
|
498
498
|
end
|
499
499
|
|
500
|
+
def test_custom_escaping
|
501
|
+
view = Class.new(Mustache) do
|
502
|
+
def escapeHTML(str)
|
503
|
+
"pong"
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
assert_equal 'pong', view.render("{{thing}}", :thing => "nothing")
|
508
|
+
assert_equal 'nothing', Mustache.render("{{thing}}", :thing => "nothing")
|
509
|
+
end
|
510
|
+
|
511
|
+
def test_implicit_iterator
|
512
|
+
view = Mustache.new
|
513
|
+
view.template = "{{#people}}* {{.}}\n{{/people}}"
|
514
|
+
view[:people] = %w( Chris Mark Scott )
|
515
|
+
|
516
|
+
assert_equal <<text, view.render
|
517
|
+
* Chris
|
518
|
+
* Mark
|
519
|
+
* Scott
|
520
|
+
text
|
521
|
+
end
|
522
|
+
|
523
|
+
def test_dot_notation
|
524
|
+
assert_equal <<-text.chomp, DotNotation.render
|
525
|
+
* Chris Firescythe
|
526
|
+
* 24
|
527
|
+
* Cincinnati, OH
|
528
|
+
* Cincinnati, OH
|
529
|
+
* Cincinnati, OH
|
530
|
+
* Normal
|
531
|
+
text
|
532
|
+
end
|
533
|
+
|
500
534
|
def test_inherited_attributes
|
501
535
|
Object.const_set :TestNamespace, Module.new
|
502
536
|
base = Class.new(Mustache)
|
data/test/spec_test.rb
CHANGED
@@ -53,11 +53,11 @@ spec_files = File.join(File.dirname(__FILE__), '..', 'ext', 'spec', 'specs', '*.
|
|
53
53
|
Dir[spec_files].each do |file|
|
54
54
|
spec = YAML.load_file(file)
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
56
|
+
klass_name = "Test" + File.basename(file, ".yml").sub(/~/, '').capitalize
|
57
|
+
instance_eval "class ::#{klass_name} < MustacheSpec; end"
|
58
|
+
test_suite = Kernel.const_get(klass_name)
|
60
59
|
|
60
|
+
test_suite.class_eval do
|
61
61
|
spec['tests'].each do |test|
|
62
62
|
define_method :"test - #{test['name']}" do
|
63
63
|
setup_partials(test)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mustache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 407
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 98
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.98.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Chris Wanstrath
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-24 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -69,6 +69,8 @@ files:
|
|
69
69
|
- test/fixtures/crazy_recursive.rb
|
70
70
|
- test/fixtures/delimiters.mustache
|
71
71
|
- test/fixtures/delimiters.rb
|
72
|
+
- test/fixtures/dot_notation.mustache
|
73
|
+
- test/fixtures/dot_notation.rb
|
72
74
|
- test/fixtures/double_section.mustache
|
73
75
|
- test/fixtures/double_section.rb
|
74
76
|
- test/fixtures/escaped.mustache
|