curly-templates 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/curly-templates.gemspec +5 -3
- data/lib/curly.rb +19 -71
- data/lib/curly/compiler.rb +60 -0
- data/lib/curly/invalid_reference.rb +13 -0
- data/lib/curly/template_handler.rb +56 -41
- data/spec/compiler_spec.rb +124 -0
- metadata +7 -5
- data/spec/curly_spec.rb +0 -123
data/curly-templates.gemspec
CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
|
|
4
4
|
s.rubygems_version = '1.3.5'
|
5
5
|
|
6
6
|
s.name = 'curly-templates'
|
7
|
-
s.version = '0.
|
8
|
-
s.date = '2013-
|
7
|
+
s.version = '0.7.0'
|
8
|
+
s.date = '2013-05-03'
|
9
9
|
|
10
10
|
s.summary = "Free your views!"
|
11
11
|
s.description = "A view layer for your Rails apps that separates structure and logic."
|
@@ -34,14 +34,16 @@ Gem::Specification.new do |s|
|
|
34
34
|
curly-templates.gemspec
|
35
35
|
lib/curly-templates.rb
|
36
36
|
lib/curly.rb
|
37
|
+
lib/curly/compiler.rb
|
37
38
|
lib/curly/dependency_tracker.rb
|
39
|
+
lib/curly/invalid_reference.rb
|
38
40
|
lib/curly/presenter.rb
|
39
41
|
lib/curly/railtie.rb
|
40
42
|
lib/curly/template_handler.rb
|
41
43
|
lib/generators/curly/controller/controller_generator.rb
|
42
44
|
lib/generators/curly/controller/templates/presenter.rb.erb
|
43
45
|
lib/generators/curly/controller/templates/view.html.curly.erb
|
44
|
-
spec/
|
46
|
+
spec/compiler_spec.rb
|
45
47
|
spec/generators/controller_generator_spec.rb
|
46
48
|
spec/presenter_spec.rb
|
47
49
|
spec/spec_helper.rb
|
data/lib/curly.rb
CHANGED
@@ -26,82 +26,30 @@
|
|
26
26
|
# See Curly::Presenter for more information on presenters.
|
27
27
|
#
|
28
28
|
module Curly
|
29
|
-
VERSION = "0.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
def message
|
41
|
-
"invalid reference `{{#{reference}}}'"
|
42
|
-
end
|
29
|
+
VERSION = "0.7.0"
|
30
|
+
|
31
|
+
# Compiles a Curly template to Ruby code.
|
32
|
+
#
|
33
|
+
# template - The template String that should be compiled.
|
34
|
+
#
|
35
|
+
# Returns a String containing the Ruby code.
|
36
|
+
def self.compile(template, presenter_class)
|
37
|
+
Compiler.compile(template, presenter_class)
|
43
38
|
end
|
44
39
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
source.gsub!(REFERENCE_REGEX) { compile_reference($1, presenter_class) }
|
55
|
-
|
56
|
-
source
|
57
|
-
end
|
58
|
-
|
59
|
-
# Whether the Curly template is valid. This includes whether all
|
60
|
-
# references are available on the presenter class.
|
61
|
-
#
|
62
|
-
# template - The template String that should be validated.
|
63
|
-
# presenter_class - The presenter Class.
|
64
|
-
#
|
65
|
-
# Returns true if the template is valid, false otherwise.
|
66
|
-
def valid?(template, presenter_class)
|
67
|
-
references = extract_references(template)
|
68
|
-
methods = presenter_class.available_methods.map(&:to_s)
|
69
|
-
references & methods == references
|
70
|
-
end
|
71
|
-
|
72
|
-
private
|
73
|
-
|
74
|
-
def compile_reference(reference, presenter_class)
|
75
|
-
method, argument = reference.split(".", 2)
|
76
|
-
|
77
|
-
unless presenter_class.method_available?(method.to_sym)
|
78
|
-
raise Curly::InvalidReference.new(method.to_sym)
|
79
|
-
end
|
80
|
-
|
81
|
-
if presenter_class.instance_method(method).arity == 1
|
82
|
-
# The method accepts a single argument -- pass it in.
|
83
|
-
code = <<-RUBY
|
84
|
-
presenter.#{method}(#{argument.inspect}) {|*args| yield(*args) }
|
85
|
-
RUBY
|
86
|
-
else
|
87
|
-
code = <<-RUBY
|
88
|
-
presenter.#{method} {|*args| yield(*args) }
|
89
|
-
RUBY
|
90
|
-
end
|
91
|
-
|
92
|
-
%(\#{
|
93
|
-
result = #{code}
|
94
|
-
ERB::Util.html_escape(result)
|
95
|
-
})
|
96
|
-
end
|
97
|
-
|
98
|
-
def extract_references(template)
|
99
|
-
template.scan(REFERENCE_REGEX).flatten
|
100
|
-
end
|
101
|
-
|
40
|
+
# Whether the Curly template is valid. This includes whether all
|
41
|
+
# references are available on the presenter class.
|
42
|
+
#
|
43
|
+
# template - The template String that should be validated.
|
44
|
+
# presenter_class - The presenter Class.
|
45
|
+
#
|
46
|
+
# Returns true if the template is valid, false otherwise.
|
47
|
+
def self.valid?(template, presenter_class)
|
48
|
+
Compiler.valid?(template, presenter_class)
|
102
49
|
end
|
103
50
|
end
|
104
51
|
|
52
|
+
require 'curly/compiler'
|
105
53
|
require 'curly/presenter'
|
106
54
|
require 'curly/template_handler'
|
107
55
|
require 'curly/railtie' if defined?(Rails)
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'curly/invalid_reference'
|
2
|
+
|
3
|
+
module Curly
|
4
|
+
class Compiler
|
5
|
+
REFERENCE_REGEX = %r(\{\{([\w\.]+)\}\})
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
# Compiles a Curly template to Ruby code.
|
10
|
+
#
|
11
|
+
# template - The template String that should be compiled.
|
12
|
+
#
|
13
|
+
# Returns a String containing the Ruby code.
|
14
|
+
def compile(template, presenter_class)
|
15
|
+
source = template.inspect
|
16
|
+
source.gsub!(REFERENCE_REGEX) { compile_reference($1, presenter_class) }
|
17
|
+
|
18
|
+
source
|
19
|
+
end
|
20
|
+
|
21
|
+
# Whether the Curly template is valid. This includes whether all
|
22
|
+
# references are available on the presenter class.
|
23
|
+
#
|
24
|
+
# template - The template String that should be validated.
|
25
|
+
# presenter_class - The presenter Class.
|
26
|
+
#
|
27
|
+
# Returns true if the template is valid, false otherwise.
|
28
|
+
def valid?(template, presenter_class)
|
29
|
+
compile(template, presenter_class)
|
30
|
+
|
31
|
+
true
|
32
|
+
rescue InvalidReference
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def compile_reference(reference, presenter_class)
|
39
|
+
method, argument = reference.split(".", 2)
|
40
|
+
|
41
|
+
unless presenter_class.method_available?(method.to_sym)
|
42
|
+
raise Curly::InvalidReference.new(method.to_sym)
|
43
|
+
end
|
44
|
+
|
45
|
+
if presenter_class.instance_method(method).arity == 1
|
46
|
+
# The method accepts a single argument -- pass it in.
|
47
|
+
code = <<-RUBY
|
48
|
+
presenter.#{method}(#{argument.inspect}) {|*args| yield(*args) }
|
49
|
+
RUBY
|
50
|
+
else
|
51
|
+
code = <<-RUBY
|
52
|
+
presenter.#{method} {|*args| yield(*args) }
|
53
|
+
RUBY
|
54
|
+
end
|
55
|
+
|
56
|
+
'#{ERB::Util.html_escape(%s)}' % code.strip
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -3,60 +3,75 @@ require 'action_view'
|
|
3
3
|
require 'curly'
|
4
4
|
|
5
5
|
class Curly::TemplateHandler
|
6
|
+
class << self
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
source = Curly.compile(template.source, presenter_class)
|
19
|
-
template_digest = Digest::MD5.hexdigest(template.source)
|
20
|
-
|
21
|
-
# Template is empty, so there's no need to initialize a presenter.
|
22
|
-
return %("") if template.source.empty?
|
23
|
-
|
24
|
-
<<-RUBY
|
25
|
-
if local_assigns.empty?
|
26
|
-
options = assigns
|
27
|
-
else
|
28
|
-
options = local_assigns
|
8
|
+
# Handles a Curly template, compiling it to Ruby code. The code will be
|
9
|
+
# evaluated in the context of an ActionView::Base instance, having access
|
10
|
+
# to a number of variables.
|
11
|
+
#
|
12
|
+
# template - The ActionView::Template template that should be compiled.
|
13
|
+
#
|
14
|
+
# Returns a String containing the Ruby code representing the template.
|
15
|
+
def call(template)
|
16
|
+
instrument(template) do
|
17
|
+
compile(template)
|
18
|
+
end
|
29
19
|
end
|
30
20
|
|
31
|
-
|
21
|
+
private
|
32
22
|
|
33
|
-
|
34
|
-
#
|
35
|
-
|
23
|
+
def compile(template)
|
24
|
+
# Template is empty, so there's no need to initialize a presenter.
|
25
|
+
return %("") if template.source.empty?
|
36
26
|
|
37
|
-
|
38
|
-
|
27
|
+
path = template.virtual_path
|
28
|
+
presenter_class = Curly::Presenter.presenter_for_path(path)
|
39
29
|
|
40
|
-
|
30
|
+
source = Curly.compile(template.source, presenter_class)
|
31
|
+
template_digest = Digest::MD5.hexdigest(template.source)
|
41
32
|
|
42
|
-
|
43
|
-
|
33
|
+
<<-RUBY
|
34
|
+
if local_assigns.empty?
|
35
|
+
options = assigns
|
44
36
|
else
|
45
|
-
|
37
|
+
options = local_assigns
|
46
38
|
end
|
47
39
|
|
48
|
-
|
49
|
-
expires_in: presenter.cache_duration
|
50
|
-
}
|
40
|
+
presenter = #{presenter_class}.new(self, options.with_indifferent_access)
|
51
41
|
|
52
|
-
|
53
|
-
|
42
|
+
view_function = lambda do
|
43
|
+
#{source}
|
54
44
|
end
|
55
45
|
|
56
|
-
|
57
|
-
|
58
|
-
|
46
|
+
if key = presenter.cache_key
|
47
|
+
@output_buffer = ActiveSupport::SafeBuffer.new
|
48
|
+
|
49
|
+
template_digest = #{template_digest.inspect}
|
50
|
+
|
51
|
+
if #{presenter_class}.respond_to?(:cache_key)
|
52
|
+
presenter_key = #{presenter_class}.cache_key
|
53
|
+
else
|
54
|
+
presenter_key = nil
|
55
|
+
end
|
56
|
+
|
57
|
+
options = {
|
58
|
+
expires_in: presenter.cache_duration
|
59
|
+
}
|
60
|
+
|
61
|
+
cache([template_digest, key, presenter_key].compact, options) do
|
62
|
+
safe_concat(view_function.call)
|
63
|
+
end
|
64
|
+
|
65
|
+
@output_buffer
|
66
|
+
else
|
67
|
+
view_function.call.html_safe
|
68
|
+
end
|
69
|
+
RUBY
|
70
|
+
end
|
71
|
+
|
72
|
+
def instrument(template, &block)
|
73
|
+
payload = { path: template.virtual_path }
|
74
|
+
ActiveSupport::Notifications.instrument("compile.curly", payload, &block)
|
59
75
|
end
|
60
|
-
RUBY
|
61
76
|
end
|
62
77
|
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Curly::Compiler do
|
4
|
+
let :presenter_class do
|
5
|
+
Class.new do
|
6
|
+
def foo
|
7
|
+
"FOO"
|
8
|
+
end
|
9
|
+
|
10
|
+
def high_yield
|
11
|
+
"#{yield}, motherfucker!"
|
12
|
+
end
|
13
|
+
|
14
|
+
def yield_value
|
15
|
+
"#{yield :foo}, please?"
|
16
|
+
end
|
17
|
+
|
18
|
+
def unicorns
|
19
|
+
"UNICORN"
|
20
|
+
end
|
21
|
+
|
22
|
+
def dirty
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def parameterized(value)
|
27
|
+
value
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.method_available?(method)
|
31
|
+
[:foo, :parameterized, :high_yield, :yield_value, :dirty].include?(method)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.available_methods
|
35
|
+
public_instance_methods
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def method_missing(*args)
|
41
|
+
"BAR"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
let(:presenter) { presenter_class.new }
|
47
|
+
|
48
|
+
describe ".compile" do
|
49
|
+
it "compiles Curly templates to Ruby code" do
|
50
|
+
evaluate("{{foo}}").should == "FOO"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "passes on an optional reference parameter to the presenter method" do
|
54
|
+
evaluate("{{parameterized.foo.bar}}").should == "foo.bar"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "passes an empty string to methods that take a parameter when none is provided" do
|
58
|
+
evaluate("{{parameterized}}").should == ""
|
59
|
+
end
|
60
|
+
|
61
|
+
it "makes sure only public methods are called on the presenter object" do
|
62
|
+
expect { evaluate("{{bar}}") }.to raise_exception(Curly::InvalidReference)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "includes the invalid reference when failing to compile" do
|
66
|
+
begin
|
67
|
+
evaluate("{{bar}}")
|
68
|
+
fail
|
69
|
+
rescue Curly::InvalidReference => e
|
70
|
+
e.reference.should == :bar
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it "propagates yields to the caller" do
|
75
|
+
evaluate("{{high_yield}}") { "$$$" }.should == "$$$, motherfucker!"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "sends along arguments passed to yield" do
|
79
|
+
evaluate("{{yield_value}}") {|v| v.upcase }.should == "FOO, please?"
|
80
|
+
end
|
81
|
+
|
82
|
+
it "escapes non HTML safe strings returned from the presenter" do
|
83
|
+
presenter.stub(:dirty) { "<p>dirty</p>" }
|
84
|
+
evaluate("{{dirty}}").should == "<p>dirty</p>"
|
85
|
+
end
|
86
|
+
|
87
|
+
it "does not escape HTML safe strings returned from the presenter" do
|
88
|
+
presenter.stub(:dirty) { "<p>dirty</p>".html_safe }
|
89
|
+
evaluate("{{dirty}}").should == "<p>dirty</p>"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe ".valid?" do
|
94
|
+
it "returns true if only available methods are referenced" do
|
95
|
+
validate("Hello, {{foo}}!").should == true
|
96
|
+
end
|
97
|
+
|
98
|
+
it "returns false if a missing method is referenced" do
|
99
|
+
validate("Hello, {{i_am_missing}}").should == false
|
100
|
+
end
|
101
|
+
|
102
|
+
it "returns false if an unavailable method is referenced" do
|
103
|
+
presenter_class.stub(:available_methods) { [:foo] }
|
104
|
+
validate("Hello, {{inspect}}").should == false
|
105
|
+
end
|
106
|
+
|
107
|
+
def validate(template)
|
108
|
+
Curly.valid?(template, presenter_class)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def evaluate(template, &block)
|
113
|
+
code = Curly::Compiler.compile(template, presenter_class)
|
114
|
+
context = double("context", presenter: presenter)
|
115
|
+
|
116
|
+
context.instance_eval(<<-RUBY)
|
117
|
+
def self.render
|
118
|
+
#{code}
|
119
|
+
end
|
120
|
+
RUBY
|
121
|
+
|
122
|
+
context.render(&block)
|
123
|
+
end
|
124
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: curly-templates
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-05-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -115,14 +115,16 @@ files:
|
|
115
115
|
- curly-templates.gemspec
|
116
116
|
- lib/curly-templates.rb
|
117
117
|
- lib/curly.rb
|
118
|
+
- lib/curly/compiler.rb
|
118
119
|
- lib/curly/dependency_tracker.rb
|
120
|
+
- lib/curly/invalid_reference.rb
|
119
121
|
- lib/curly/presenter.rb
|
120
122
|
- lib/curly/railtie.rb
|
121
123
|
- lib/curly/template_handler.rb
|
122
124
|
- lib/generators/curly/controller/controller_generator.rb
|
123
125
|
- lib/generators/curly/controller/templates/presenter.rb.erb
|
124
126
|
- lib/generators/curly/controller/templates/view.html.curly.erb
|
125
|
-
- spec/
|
127
|
+
- spec/compiler_spec.rb
|
126
128
|
- spec/generators/controller_generator_spec.rb
|
127
129
|
- spec/presenter_spec.rb
|
128
130
|
- spec/spec_helper.rb
|
@@ -143,7 +145,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
143
145
|
version: '0'
|
144
146
|
segments:
|
145
147
|
- 0
|
146
|
-
hash:
|
148
|
+
hash: -1185334728510665354
|
147
149
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
150
|
none: false
|
149
151
|
requirements:
|
@@ -157,7 +159,7 @@ signing_key:
|
|
157
159
|
specification_version: 2
|
158
160
|
summary: Free your views!
|
159
161
|
test_files:
|
160
|
-
- spec/
|
162
|
+
- spec/compiler_spec.rb
|
161
163
|
- spec/generators/controller_generator_spec.rb
|
162
164
|
- spec/presenter_spec.rb
|
163
165
|
- spec/template_handler_spec.rb
|
data/spec/curly_spec.rb
DELETED
@@ -1,123 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'curly'
|
3
|
-
|
4
|
-
describe Curly do
|
5
|
-
let :presenter_class do
|
6
|
-
Class.new do
|
7
|
-
def foo
|
8
|
-
"FOO"
|
9
|
-
end
|
10
|
-
|
11
|
-
def high_yield
|
12
|
-
"#{yield}, motherfucker!"
|
13
|
-
end
|
14
|
-
|
15
|
-
def yield_value
|
16
|
-
"#{yield :foo}, please?"
|
17
|
-
end
|
18
|
-
|
19
|
-
def unicorns
|
20
|
-
"UNICORN"
|
21
|
-
end
|
22
|
-
|
23
|
-
def dirty
|
24
|
-
nil
|
25
|
-
end
|
26
|
-
|
27
|
-
def parameterized(value)
|
28
|
-
value
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.method_available?(method)
|
32
|
-
[:foo, :parameterized, :high_yield, :yield_value, :dirty].include?(method)
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.available_methods
|
36
|
-
public_instance_methods
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def method_missing(*args)
|
42
|
-
"BAR"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
let(:presenter) { presenter_class.new }
|
48
|
-
|
49
|
-
it "compiles Curly templates to Ruby code" do
|
50
|
-
evaluate("{{foo}}").should == "FOO"
|
51
|
-
end
|
52
|
-
|
53
|
-
it "passes on an optional reference parameter to the presenter method" do
|
54
|
-
evaluate("{{parameterized.foo.bar}}").should == "foo.bar"
|
55
|
-
end
|
56
|
-
|
57
|
-
it "passes an empty string to methods that take a parameter when none is provided" do
|
58
|
-
evaluate("{{parameterized}}").should == ""
|
59
|
-
end
|
60
|
-
|
61
|
-
it "makes sure only public methods are called on the presenter object" do
|
62
|
-
expect { evaluate("{{bar}}") }.to raise_exception(Curly::InvalidReference)
|
63
|
-
end
|
64
|
-
|
65
|
-
it "includes the invalid reference when failing to compile" do
|
66
|
-
begin
|
67
|
-
evaluate("{{bar}}")
|
68
|
-
fail
|
69
|
-
rescue Curly::InvalidReference => e
|
70
|
-
e.reference.should == :bar
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
it "propagates yields to the caller" do
|
75
|
-
evaluate("{{high_yield}}") { "$$$" }.should == "$$$, motherfucker!"
|
76
|
-
end
|
77
|
-
|
78
|
-
it "sends along arguments passed to yield" do
|
79
|
-
evaluate("{{yield_value}}") {|v| v.upcase }.should == "FOO, please?"
|
80
|
-
end
|
81
|
-
|
82
|
-
it "escapes non HTML safe strings returned from the presenter" do
|
83
|
-
presenter.stub(:dirty) { "<p>dirty</p>" }
|
84
|
-
evaluate("{{dirty}}").should == "<p>dirty</p>"
|
85
|
-
end
|
86
|
-
|
87
|
-
it "does not escape HTML safe strings returned from the presenter" do
|
88
|
-
presenter.stub(:dirty) { "<p>dirty</p>".html_safe }
|
89
|
-
evaluate("{{dirty}}").should == "<p>dirty</p>"
|
90
|
-
end
|
91
|
-
|
92
|
-
describe ".valid?" do
|
93
|
-
it "returns true if only available methods are referenced" do
|
94
|
-
validate("Hello, {{foo}}!").should == true
|
95
|
-
end
|
96
|
-
|
97
|
-
it "returns false if a missing method is referenced" do
|
98
|
-
validate("Hello, {{i_am_missing}}").should == false
|
99
|
-
end
|
100
|
-
|
101
|
-
it "returns false if an unavailable method is referenced" do
|
102
|
-
presenter_class.stub(:available_methods) { [:foo] }
|
103
|
-
validate("Hello, {{inspect}}").should == false
|
104
|
-
end
|
105
|
-
|
106
|
-
def validate(template)
|
107
|
-
Curly.valid?(template, presenter_class)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def evaluate(template, &block)
|
112
|
-
code = Curly.compile(template, presenter_class)
|
113
|
-
context = double("context", presenter: presenter)
|
114
|
-
|
115
|
-
context.instance_eval(<<-RUBY)
|
116
|
-
def self.render
|
117
|
-
#{code}
|
118
|
-
end
|
119
|
-
RUBY
|
120
|
-
|
121
|
-
context.render(&block)
|
122
|
-
end
|
123
|
-
end
|