curly-templates 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.5.0'
8
- s.date = '2013-04-19'
7
+ s.version = '0.6.0'
8
+ s.date = '2013-04-22'
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."
data/lib/curly.rb CHANGED
@@ -26,11 +26,20 @@
26
26
  # See Curly::Presenter for more information on presenters.
27
27
  #
28
28
  module Curly
29
- VERSION = "0.5.0"
29
+ VERSION = "0.6.0"
30
30
 
31
31
  REFERENCE_REGEX = %r(\{\{([\w\.]+)\}\})
32
32
 
33
33
  class InvalidReference < StandardError
34
+ attr_reader :reference
35
+
36
+ def initialize(reference)
37
+ @reference = reference
38
+ end
39
+
40
+ def message
41
+ "invalid reference `{{#{reference}}}'"
42
+ end
34
43
  end
35
44
 
36
45
  class << self
@@ -40,9 +49,9 @@ module Curly
40
49
  # template - The template String that should be compiled.
41
50
  #
42
51
  # Returns a String containing the Ruby code.
43
- def compile(template)
52
+ def compile(template, presenter_class)
44
53
  source = template.inspect
45
- source.gsub!(REFERENCE_REGEX) { compile_reference($1) }
54
+ source.gsub!(REFERENCE_REGEX) { compile_reference($1, presenter_class) }
46
55
 
47
56
  source
48
57
  end
@@ -62,20 +71,26 @@ module Curly
62
71
 
63
72
  private
64
73
 
65
- def compile_reference(reference)
74
+ def compile_reference(reference, presenter_class)
66
75
  method, argument = reference.split(".", 2)
67
76
 
68
- %(\#{
69
- unless presenter.method_available?(:#{method})
70
- raise Curly::InvalidReference, "invalid reference `{{#{reference}}}'"
71
- end
77
+ unless presenter_class.method_available?(method.to_sym)
78
+ raise Curly::InvalidReference.new(method.to_sym)
79
+ end
72
80
 
73
- if presenter.method(:#{method}).arity == 1
74
- result = presenter.#{method}(#{argument.inspect}) {|*args| yield(*args) }
75
- else
76
- result = presenter.#{method} {|*args| yield(*args) }
77
- end
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
78
91
 
92
+ %(\#{
93
+ result = #{code}
79
94
  ERB::Util.html_escape(result)
80
95
  })
81
96
  end
@@ -84,24 +84,6 @@ module Curly
84
84
  nil
85
85
  end
86
86
 
87
- # Whether a method is available to templates rendered with the presenter.
88
- #
89
- # Templates can reference "variables", which are simply methods defined on
90
- # the presenter. By default, only public instance methods can be
91
- # referenced, and any method defined on Curly::Presenter itself cannot be
92
- # referenced. This means that methods such as `#cache_key` and #inspect are
93
- # not available. This is done for safety purposes.
94
- #
95
- # This policy can be changed by overriding this method in your presenters.
96
- #
97
- # method - The Symbol name of the method.
98
- #
99
- # Returns true if the method can be referenced by a template,
100
- # false otherwise.
101
- def method_available?(method)
102
- self.class.available_methods.include?(method)
103
- end
104
-
105
87
  class << self
106
88
 
107
89
  # The name of the presenter class for a given view path.
@@ -122,6 +104,24 @@ module Curly
122
104
  presenter_name_for_path(path).constantize rescue nil
123
105
  end
124
106
 
107
+ # Whether a method is available to templates rendered with the presenter.
108
+ #
109
+ # Templates can reference "variables", which are simply methods defined on
110
+ # the presenter. By default, only public instance methods can be
111
+ # referenced, and any method defined on Curly::Presenter itself cannot be
112
+ # referenced. This means that methods such as `#cache_key` and #inspect are
113
+ # not available. This is done for safety purposes.
114
+ #
115
+ # This policy can be changed by overriding this method in your presenters.
116
+ #
117
+ # method - The Symbol name of the method.
118
+ #
119
+ # Returns true if the method can be referenced by a template,
120
+ # false otherwise.
121
+ def method_available?(method)
122
+ available_methods.include?(method)
123
+ end
124
+
125
125
  # A list of methods available to templates rendered with the presenter.
126
126
  #
127
127
  # Returns an Array of Symbol method names.
@@ -13,9 +13,9 @@ class Curly::TemplateHandler
13
13
  # Returns a String containing the Ruby code representing the template.
14
14
  def self.call(template)
15
15
  path = template.virtual_path
16
- presenter_class = Curly::Presenter.presenter_name_for_path(path)
16
+ presenter_class = Curly::Presenter.presenter_for_path(path)
17
17
 
18
- source = Curly.compile(template.source)
18
+ source = Curly.compile(template.source, presenter_class)
19
19
  template_digest = Digest::MD5.hexdigest(template.source)
20
20
 
21
21
  # Template is empty, so there's no need to initialize a presenter.
data/spec/curly_spec.rb CHANGED
@@ -20,11 +20,15 @@ describe Curly do
20
20
  "UNICORN"
21
21
  end
22
22
 
23
+ def dirty
24
+ nil
25
+ end
26
+
23
27
  def parameterized(value)
24
28
  value
25
29
  end
26
30
 
27
- def method_available?(method)
31
+ def self.method_available?(method)
28
32
  [:foo, :parameterized, :high_yield, :yield_value, :dirty].include?(method)
29
33
  end
30
34
 
@@ -58,6 +62,15 @@ describe Curly do
58
62
  expect { evaluate("{{bar}}") }.to raise_exception(Curly::InvalidReference)
59
63
  end
60
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
+
61
74
  it "propagates yields to the caller" do
62
75
  evaluate("{{high_yield}}") { "$$$" }.should == "$$$, motherfucker!"
63
76
  end
@@ -96,7 +109,7 @@ describe Curly do
96
109
  end
97
110
 
98
111
  def evaluate(template, &block)
99
- code = Curly.compile(template)
112
+ code = Curly.compile(template, presenter_class)
100
113
  context = double("context", presenter: presenter)
101
114
 
102
115
  context.instance_eval(<<-RUBY)
@@ -25,7 +25,7 @@ describe Curly::TemplateHandler do
25
25
  @cache_duration
26
26
  end
27
27
 
28
- def method_available?(method)
28
+ def self.method_available?(method)
29
29
  true
30
30
  end
31
31
  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.5.0
4
+ version: 0.6.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-04-19 00:00:00.000000000 Z
12
+ date: 2013-04-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -143,7 +143,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
143
143
  version: '0'
144
144
  segments:
145
145
  - 0
146
- hash: 4267343467533588102
146
+ hash: -673817575168436386
147
147
  required_rubygems_version: !ruby/object:Gem::Requirement
148
148
  none: false
149
149
  requirements: