curtain 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/README.md +311 -17
- data/TODO.md +7 -0
- data/curtain.gemspec +2 -3
- data/erubs_example.rb +103 -0
- data/example.erb +4 -0
- data/example.slim +2 -0
- data/lib/curtain/caching.rb +9 -0
- data/lib/curtain/erubis.rb +33 -0
- data/lib/curtain/erubis_template.rb +23 -0
- data/lib/curtain/form_builder.rb +218 -0
- data/lib/curtain/form_helpers.rb +23 -0
- data/lib/curtain/html_helpers.rb +180 -0
- data/lib/curtain/output_buffer.rb +10 -0
- data/lib/curtain/rendering.rb +9 -30
- data/lib/curtain/templating.rb +5 -1
- data/lib/curtain/version.rb +1 -1
- data/lib/curtain.rb +18 -1
- data/test/basic_test.rb +66 -0
- data/test/cache_test.rb +17 -0
- data/test/examples/{body.erb → basic/erb/body.erb} +0 -0
- data/test/examples/basic/erb/index.erb +1 -0
- data/test/examples/basic/erb/layout.erb +3 -0
- data/test/examples/{subdir → basic/erb/subdir}/index.erb +0 -0
- data/test/examples/{test.erb → basic/erb/test.erb} +0 -0
- data/test/examples/basic/slim/body.slim +5 -0
- data/test/examples/basic/slim/index.slim +1 -0
- data/test/examples/basic/slim/layout.slim +2 -0
- data/test/examples/basic/slim/subdir/index.slim +1 -0
- data/test/examples/basic/slim/test.slim +3 -0
- data/test/examples/cache/erb/cache.erb +3 -0
- data/test/examples/cache/slim/cache.slim +2 -0
- data/test/examples/form/Rakefile +56 -0
- data/test/examples/form/account.html +101 -0
- data/test/examples/form/account.rb +11 -0
- data/test/examples/form/account.yml +11 -0
- data/test/examples/form/account_view.rb +3 -0
- data/test/examples/form/account_with_data.html +100 -0
- data/test/examples/form/erb/account.erb +84 -0
- data/test/examples/form/erb/account_with_fields.erb +0 -0
- data/test/examples/form/erb/bootstrap.erb +15 -0
- data/test/examples/form/slim/account.slim +65 -0
- data/test/examples/form/slim/bootstrap.slim +11 -0
- data/test/examples/html/erb/content_tag.erb +1 -0
- data/test/examples/html/erb/content_tag_with_content.erb +1 -0
- data/test/examples/html/erb/content_tag_with_content_and_attributes.erb +1 -0
- data/test/examples/html/erb/content_tag_with_content_block_and_attributes.erb +3 -0
- data/test/examples/html/erb/content_tag_with_content_block_with_nested_tags.erb +3 -0
- data/test/examples/html/erb/empty_content_tag.erb +1 -0
- data/test/examples/html/erb/void_tag.erb +1 -0
- data/test/examples/html/erb/void_tag_with_attributes.erb +1 -0
- data/test/examples/html/slim/content_tag.slim +1 -0
- data/test/examples/html/slim/content_tag_with_content.slim +1 -0
- data/test/examples/html/slim/content_tag_with_content_and_attributes.slim +1 -0
- data/test/examples/html/slim/content_tag_with_content_block_and_attributes.slim +2 -0
- data/test/examples/html/slim/content_tag_with_content_block_with_nested_tags.slim +2 -0
- data/test/examples/html/slim/empty_content_tag.slim +1 -0
- data/test/examples/html/slim/void_tag.slim +1 -0
- data/test/examples/html/slim/void_tag_with_attributes.slim +1 -0
- data/test/form_test.rb +44 -0
- data/test/html_test.rb +32 -0
- data/test/test_helper.rb +31 -2
- metadata +101 -34
- data/test/curtain_test.rb +0 -119
- data/test/examples/index.erb +0 -1
- data/test/examples/layout.erb +0 -1
- data/test/examples/registration.mustache +0 -48
- data/test/examples/simple.erb +0 -1
@@ -0,0 +1,218 @@
|
|
1
|
+
module Curtain
|
2
|
+
class FormBuilder
|
3
|
+
include HTMLHelpers
|
4
|
+
|
5
|
+
attr_accessor :object
|
6
|
+
|
7
|
+
def initialize(object=nil)
|
8
|
+
self.object = object
|
9
|
+
end
|
10
|
+
|
11
|
+
def form_object(object)
|
12
|
+
prev_object = self.object
|
13
|
+
self.object = object
|
14
|
+
yield
|
15
|
+
self.object = prev_object
|
16
|
+
object
|
17
|
+
end
|
18
|
+
|
19
|
+
def label(content=nil, attrs={}, &body)
|
20
|
+
if content.is_a?(Symbol)
|
21
|
+
attrs = { for: content }.merge(attrs)
|
22
|
+
content = content.to_s.titleize
|
23
|
+
end
|
24
|
+
content_tag(:label, content, attrs, &body)
|
25
|
+
end
|
26
|
+
|
27
|
+
NO_VALUE_INPUT_TYPES = %w[checkbox file password radio]
|
28
|
+
|
29
|
+
def input(name=nil, attrs={})
|
30
|
+
if name.is_a?(Hash)
|
31
|
+
name = nil
|
32
|
+
attrs = name
|
33
|
+
end
|
34
|
+
|
35
|
+
if name
|
36
|
+
new_attrs = { name: name }
|
37
|
+
|
38
|
+
if object && !NO_VALUE_INPUT_TYPES.include?(attrs[:type])
|
39
|
+
new_attrs[:value] = object.try(name)
|
40
|
+
end
|
41
|
+
|
42
|
+
unless attrs.has_key?(:id) && !attrs[:id]
|
43
|
+
attrs = attrs.merge(id: name)
|
44
|
+
end
|
45
|
+
|
46
|
+
attrs = new_attrs.merge(attrs)
|
47
|
+
end
|
48
|
+
|
49
|
+
void_tag(:input, attrs)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @!method color(name, attrs={})
|
53
|
+
# @param name [String] The value for the name attribute
|
54
|
+
# @param attrs [Hash] The attributes for the tag
|
55
|
+
# @return [String] HTML input tag with type="color"
|
56
|
+
# @!method date(name, attrs={})
|
57
|
+
# @param name [String] The value for the name attribute
|
58
|
+
# @param attrs [Hash] The attributes for the tag
|
59
|
+
# @return [String] HTML input tag with type="date"
|
60
|
+
# @!method datetime(name, attrs={})
|
61
|
+
# @param name [String] The value for the name attribute
|
62
|
+
# @param attrs [Hash] The attributes for the tag
|
63
|
+
# @return [String] HTML input tag with type="datetime"
|
64
|
+
# @!method datetime_local(name, attrs={})
|
65
|
+
# @param name [String] The value for the name attribute
|
66
|
+
# @param attrs [Hash] The attributes for the tag
|
67
|
+
# @return [String] HTML input tag with type="datetime_local"
|
68
|
+
# @!method email(name, attrs={})
|
69
|
+
# @param name [String] The value for the name attribute
|
70
|
+
# @param attrs [Hash] The attributes for the tag
|
71
|
+
# @return [String] HTML input tag with type="email"
|
72
|
+
# @!method file(name, attrs={})
|
73
|
+
# @param name [String] The value for the name attribute
|
74
|
+
# @param attrs [Hash] The attributes for the tag
|
75
|
+
# @return [String] HTML input tag with type="file"
|
76
|
+
# @!method hidden(name, attrs={})
|
77
|
+
# @param name [String] The value for the name attribute
|
78
|
+
# @param attrs [Hash] The attributes for the tag
|
79
|
+
# @return [String] HTML input tag with type="hidden"
|
80
|
+
# @!method image(name, attrs={})
|
81
|
+
# @param name [String] The value for the name attribute
|
82
|
+
# @param attrs [Hash] The attributes for the tag
|
83
|
+
# @return [String] HTML input tag with type="image"
|
84
|
+
# @!method month(name, attrs={})
|
85
|
+
# @param name [String] The value for the name attribute
|
86
|
+
# @param attrs [Hash] The attributes for the tag
|
87
|
+
# @return [String] HTML input tag with type="month"
|
88
|
+
# @!method number(name, attrs={})
|
89
|
+
# @param name [String] The value for the name attribute
|
90
|
+
# @param attrs [Hash] The attributes for the tag
|
91
|
+
# @return [String] HTML input tag with type="number"
|
92
|
+
# @!method password(name, attrs={})
|
93
|
+
# @param name [String] The value for the name attribute
|
94
|
+
# @param attrs [Hash] The attributes for the tag
|
95
|
+
# @return [String] HTML input tag with type="password"
|
96
|
+
# @!method range(name, attrs={})
|
97
|
+
# @param name [String] The value for the name attribute
|
98
|
+
# @param attrs [Hash] The attributes for the tag
|
99
|
+
# @return [String] HTML input tag with type="range"
|
100
|
+
# @!method search(name, attrs={})
|
101
|
+
# @param name [String] The value for the name attribute
|
102
|
+
# @param attrs [Hash] The attributes for the tag
|
103
|
+
# @return [String] HTML input tag with type="search"
|
104
|
+
# @!method tel(name, attrs={})
|
105
|
+
# @param name [String] The value for the name attribute
|
106
|
+
# @param attrs [Hash] The attributes for the tag
|
107
|
+
# @return [String] HTML input tag with type="tel"
|
108
|
+
# @!method text(name, attrs={})
|
109
|
+
# @param name [String] The value for the name attribute
|
110
|
+
# @param attrs [Hash] The attributes for the tag
|
111
|
+
# @return [String] HTML input tag with type="text"
|
112
|
+
# @!method time(name, attrs={})
|
113
|
+
# @param name [String] The value for the name attribute
|
114
|
+
# @param attrs [Hash] The attributes for the tag
|
115
|
+
# @return [String] HTML input tag with type="time"
|
116
|
+
# @!method url(name, attrs={})
|
117
|
+
# @param name [String] The value for the name attribute
|
118
|
+
# @param attrs [Hash] The attributes for the tag
|
119
|
+
# @return [String] HTML input tag with type="url"
|
120
|
+
# @!method week(name, attrs={})
|
121
|
+
# @param name [String] The value for the name attribute
|
122
|
+
# @param attrs [Hash] The attributes for the tag
|
123
|
+
# @return [String] HTML input tag with type="week"P
|
124
|
+
INPUT_TAG_NAMES = [
|
125
|
+
:checkbox,
|
126
|
+
:color,
|
127
|
+
:date,
|
128
|
+
:datetime,
|
129
|
+
:datetime_local,
|
130
|
+
:email,
|
131
|
+
:file,
|
132
|
+
:hidden,
|
133
|
+
:image,
|
134
|
+
:month,
|
135
|
+
:number,
|
136
|
+
:password,
|
137
|
+
:radio,
|
138
|
+
:range ,
|
139
|
+
:search,
|
140
|
+
:tel,
|
141
|
+
:text,
|
142
|
+
:time ,
|
143
|
+
:url,
|
144
|
+
:week
|
145
|
+
].each do |tag|
|
146
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
147
|
+
def #{tag}(name, attrs={})
|
148
|
+
input(name, { type: '#{tag.to_s.gsub('_','-')}' }.merge(attrs))
|
149
|
+
end
|
150
|
+
METHOD
|
151
|
+
end
|
152
|
+
|
153
|
+
#@param name [String] The value for the name attribute
|
154
|
+
#@param attrs [Hash] The attributes for the tag
|
155
|
+
#@return [String] HTML input tag with type="checkbox"
|
156
|
+
def checkbox(name, attrs={})
|
157
|
+
input(:checkbox, { type: 'checkbox', value: 'true', checked: !!object.try(name) }.merge(attrs))
|
158
|
+
end
|
159
|
+
|
160
|
+
#@param name [String] The value for the name attribute
|
161
|
+
#@param attrs [Hash] The attributes for the tag
|
162
|
+
#@return [String] HTML input tag with type="radio"
|
163
|
+
def radio(name, attrs={})
|
164
|
+
input(:radio, { type: 'radio', checked: (attrs.has_key?(:value) && attrs[:value].to_s == object.try(name).to_s) }.merge(attrs))
|
165
|
+
end
|
166
|
+
|
167
|
+
def select(name, attrs={}, &body)
|
168
|
+
attrs = attrs.dup
|
169
|
+
if name.is_a?(Hash)
|
170
|
+
name = nil
|
171
|
+
attrs = name
|
172
|
+
end
|
173
|
+
|
174
|
+
selected = attrs[:selected]
|
175
|
+
if name
|
176
|
+
new_attrs = { name: name }
|
177
|
+
|
178
|
+
selected ||= object.try(name) if object
|
179
|
+
|
180
|
+
unless attrs.has_key?(:id) && !attrs[:id]
|
181
|
+
attrs = attrs.merge(id: name)
|
182
|
+
end
|
183
|
+
|
184
|
+
attrs = new_attrs.merge(attrs)
|
185
|
+
end
|
186
|
+
|
187
|
+
if options = attrs.delete(:options)
|
188
|
+
content = "\n".html_safe
|
189
|
+
options.each do |o|
|
190
|
+
if o.is_a?(Array)
|
191
|
+
text = o.first
|
192
|
+
value = o.last
|
193
|
+
else
|
194
|
+
text = o
|
195
|
+
value = o
|
196
|
+
end
|
197
|
+
content << option(text, value: value, selected: (!selected.nil? && value.to_s == selected.to_s))
|
198
|
+
content << "\n"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
content_tag(:select, content, attrs, &body)
|
203
|
+
end
|
204
|
+
|
205
|
+
def textarea(name, attrs={}, &body)
|
206
|
+
content_tag(:textarea, object.try(name), attrs, &body)
|
207
|
+
end
|
208
|
+
|
209
|
+
def button(content=nil, attrs={}, &body)
|
210
|
+
content_tag(:button, content, attrs, &body)
|
211
|
+
end
|
212
|
+
|
213
|
+
def submit(content=nil, attrs={}, &body)
|
214
|
+
button(content, { type: 'submit' }.merge(attrs), &body)
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
218
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Curtain
|
2
|
+
module FormHelpers
|
3
|
+
|
4
|
+
def self.included(cls)
|
5
|
+
cls.class_eval do
|
6
|
+
attr_accessor :current_form
|
7
|
+
|
8
|
+
delegate :button, :checkbox, :color, :date, :datetime, :email, :file, :hidden, :image, :input, :label, :month, :number, :password, :radio, :range, :reset, :search, :select, :submit, :tel, :text, :textarea, :time, :url, :week, :to => :current_form
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def form(attrs={}, &body)
|
13
|
+
# Have a property for a default form builder
|
14
|
+
# Accept builder and object attrs
|
15
|
+
# Allow for custom builder classes
|
16
|
+
attrs = attrs.dup
|
17
|
+
self.current_form = FormBuilder.new(attrs.delete(:for))
|
18
|
+
content = content_tag(:form, attrs, &body)
|
19
|
+
self.current_form = nil
|
20
|
+
content
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
module Curtain
|
2
|
+
module HTMLHelpers
|
3
|
+
def capture
|
4
|
+
original_buffer = @output_buffer
|
5
|
+
@output_buffer = Curtain::OutputBuffer.new
|
6
|
+
yield
|
7
|
+
ensure
|
8
|
+
@output_buffer = original_buffer
|
9
|
+
end
|
10
|
+
|
11
|
+
# Generates a tag that has no content.
|
12
|
+
#
|
13
|
+
# @example Tag with no attributes
|
14
|
+
# view.void_tag(:br) # => "<br>"
|
15
|
+
#
|
16
|
+
# @example Tag with attributes
|
17
|
+
# view.void_tag(:img, src: "/logo.png") # => '<img src="/logo.png">'
|
18
|
+
#
|
19
|
+
# @param name [Symbol, String] The name of the tag
|
20
|
+
# @param attrs [Hash] The attributes of the tag
|
21
|
+
#
|
22
|
+
# @return [String] The HTML tag
|
23
|
+
#
|
24
|
+
def void_tag(name, attrs={})
|
25
|
+
tag_opening(name, attrs) << ">".html_safe
|
26
|
+
end
|
27
|
+
|
28
|
+
# Generates a with opening and closing tags and potentially content.
|
29
|
+
#
|
30
|
+
# @example Tag with no attributes, no content
|
31
|
+
# content_tag(:p) # => "<p></p>"
|
32
|
+
#
|
33
|
+
# @example Tag with content
|
34
|
+
# content_tag(:p, "Hello") # => "<p>Hello</p>"
|
35
|
+
#
|
36
|
+
# @example Tag with block content
|
37
|
+
# content_tag(:p) { "Hello" } # => "<p>Hello</p>"
|
38
|
+
#
|
39
|
+
# @example Tag with content and attributes
|
40
|
+
# content_tag(:a, "Log In", href: "/log_in") # => "<a href="/log_in">Log In</a>"
|
41
|
+
#
|
42
|
+
# @example Tag with content block and attributes
|
43
|
+
# content_tag(:a, href: "/log_in") { "Log In" } # => "<a href="/log_in">Log In</a>"
|
44
|
+
#
|
45
|
+
# @param name [Symbol, String] The name of the tag
|
46
|
+
# @param attrs [Hash] The attributes of the tag
|
47
|
+
#
|
48
|
+
# @return [String] The HTML tag
|
49
|
+
#
|
50
|
+
def content_tag(name, content=nil, attrs={}, &body)
|
51
|
+
if content.is_a?(Hash)
|
52
|
+
attrs = content
|
53
|
+
content = nil
|
54
|
+
end
|
55
|
+
|
56
|
+
if block_given?
|
57
|
+
content = capture(&body)
|
58
|
+
end
|
59
|
+
|
60
|
+
tag = tag_opening(name, attrs)
|
61
|
+
tag << ">".html_safe
|
62
|
+
tag << content
|
63
|
+
tag << "</#{name}>".html_safe
|
64
|
+
end
|
65
|
+
|
66
|
+
# Tags
|
67
|
+
|
68
|
+
# @!method br(attrs={})
|
69
|
+
# @param attrs [Hash] The attributes
|
70
|
+
# @return [String] HTML br tag
|
71
|
+
# @!method hr(attrs={})
|
72
|
+
# @!method img(attrs={})
|
73
|
+
VOID_TAGS = [
|
74
|
+
:br,
|
75
|
+
:hr,
|
76
|
+
:img
|
77
|
+
].each do |tag|
|
78
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
79
|
+
def #{tag}(attrs={})
|
80
|
+
void_tag(#{tag.inspect}, attrs)
|
81
|
+
end
|
82
|
+
METHOD
|
83
|
+
end
|
84
|
+
|
85
|
+
# @!method a(content=nil, attrs={}, &body)
|
86
|
+
# @return [String] HTML a tag
|
87
|
+
# @!method b(content=nil, attrs={}, &body)
|
88
|
+
# @return [String] HTML b tag
|
89
|
+
# @!method dd(content=nil, attrs={}, &body)
|
90
|
+
# @return [String] HTML dd tag
|
91
|
+
# @!method div(content=nil, attrs={}, &body)
|
92
|
+
# @return [String] HTML div tag
|
93
|
+
# @!method dl(content=nil, attrs={}, &body)
|
94
|
+
# @return [String] HTML dl tag
|
95
|
+
# @!method dt(content=nil, attrs={}, &body)
|
96
|
+
# @return [String] HTML dt tag
|
97
|
+
# @!method h1(content=nil, attrs={}, &body)
|
98
|
+
# @return [String] HTML h1 tag
|
99
|
+
# @!method h2(content=nil, attrs={}, &body)
|
100
|
+
# @return [String] HTML h2 tag
|
101
|
+
# @!method h3(content=nil, attrs={}, &body)
|
102
|
+
# @return [String] HTML h3 tag
|
103
|
+
# @!method h4(content=nil, attrs={}, &body)
|
104
|
+
# @return [String] HTML h4 tag
|
105
|
+
# @!method h5(content=nil, attrs={}, &body)
|
106
|
+
# @return [String] HTML h5 tag
|
107
|
+
# @!method h6(content=nil, attrs={}, &body)
|
108
|
+
# @return [String] HTML h6 tag
|
109
|
+
# @!method i(content=nil, attrs={}, &body)
|
110
|
+
# @return [String] HTML i tag
|
111
|
+
# @!method p(content=nil, attrs={}, &body)
|
112
|
+
# @return [String] HTML p tag
|
113
|
+
# @!method table(content=nil, attrs={}, &body)
|
114
|
+
# @return [String] HTML table tag
|
115
|
+
# @!method tbody(content=nil, attrs={}, &body)
|
116
|
+
# @return [String] HTML tbody tag
|
117
|
+
# @!method td(content=nil, attrs={}, &body)
|
118
|
+
# @return [String] HTML td tag
|
119
|
+
# @!method tfoot(content=nil, attrs={}, &body)
|
120
|
+
# @return [String] HTML tfoot tag
|
121
|
+
# @!method th(content=nil, attrs={}, &body)
|
122
|
+
# @return [String] HTML th tag
|
123
|
+
# @!method thead(content=nil, attrs={}, &body)
|
124
|
+
# @return [String] HTML thead tag
|
125
|
+
# @!method tr(content=nil, attrs={}, &body)
|
126
|
+
# @return [String] HTML tr tag#
|
127
|
+
CONTENT_TAGS = [
|
128
|
+
:a,
|
129
|
+
:b,
|
130
|
+
:dd,
|
131
|
+
:div,
|
132
|
+
:dl,
|
133
|
+
:dt,
|
134
|
+
:h1,
|
135
|
+
:h2,
|
136
|
+
:h3,
|
137
|
+
:h4,
|
138
|
+
:h5,
|
139
|
+
:h6,
|
140
|
+
:i,
|
141
|
+
:li,
|
142
|
+
:option,
|
143
|
+
:p,
|
144
|
+
:section,
|
145
|
+
:table,
|
146
|
+
:tbody,
|
147
|
+
:td,
|
148
|
+
:tfoot,
|
149
|
+
:th,
|
150
|
+
:thead,
|
151
|
+
:tr,
|
152
|
+
:ul
|
153
|
+
].each do |tag|
|
154
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
155
|
+
def #{tag}(content=nil, attrs={}, &body)
|
156
|
+
content_tag(#{tag.inspect}, content, attrs, &body)
|
157
|
+
end
|
158
|
+
METHOD
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
def tag_opening(name, attrs={})
|
163
|
+
tag = "<#{name}".html_safe
|
164
|
+
|
165
|
+
if attrs
|
166
|
+
attrs.each do |name, value|
|
167
|
+
if value == true
|
168
|
+
tag << %{ #{name}}.html_safe
|
169
|
+
elsif value != false
|
170
|
+
tag << %{ #{name}="}.html_safe
|
171
|
+
tag << value
|
172
|
+
tag << '"'.html_safe
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
tag
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
data/lib/curtain/rendering.rb
CHANGED
@@ -1,26 +1,8 @@
|
|
1
1
|
require 'tilt'
|
2
|
+
require 'temple'
|
2
3
|
|
3
4
|
module Curtain
|
4
5
|
|
5
|
-
class MustacheRenderer < ::Mustache
|
6
|
-
def initialize(view, template_file)
|
7
|
-
@view = view
|
8
|
-
@template_file = template_file
|
9
|
-
end
|
10
|
-
|
11
|
-
def respond_to?(method_name)
|
12
|
-
super || @view.respond_to?(method_name)
|
13
|
-
end
|
14
|
-
|
15
|
-
def method_missing(name, *args, &block)
|
16
|
-
if @view.respond_to?(name)
|
17
|
-
@view.send(name, *args, &block)
|
18
|
-
else
|
19
|
-
super
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
6
|
module Rendering
|
25
7
|
# Renders the template
|
26
8
|
#
|
@@ -28,7 +10,7 @@ module Curtain
|
|
28
10
|
# view.render
|
29
11
|
#
|
30
12
|
# @example Render the foo template
|
31
|
-
# view.render "foo.
|
13
|
+
# view.render "foo.slim"
|
32
14
|
#
|
33
15
|
# @example You can use symbols and omit the extension
|
34
16
|
# view.render :foo
|
@@ -58,16 +40,13 @@ module Curtain
|
|
58
40
|
template_file = self.class.find_template(name)
|
59
41
|
ext = template_file.split('.').last
|
60
42
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
template = Tilt.new(template_file)
|
69
|
-
template.render(self, variables.merge(locals))
|
70
|
-
end
|
43
|
+
orig_buffer = @output_buffer
|
44
|
+
@output_buffer = Curtain::OutputBuffer.new
|
45
|
+
template = Tilt.new(template_file, :buffer => '@output_buffer', :use_html_safe => true, :disable_capture => true, :generator => Temple::Generators::RailsOutputBuffer )
|
46
|
+
template.render(self, variables.merge(locals))
|
47
|
+
@output_buffer
|
48
|
+
ensure
|
49
|
+
@output_buffer = orig_buffer
|
71
50
|
end
|
72
51
|
end
|
73
52
|
end
|
data/lib/curtain/templating.rb
CHANGED
@@ -45,9 +45,13 @@ module Curtain
|
|
45
45
|
raise TemplateNotFound.new("Could not find a template matching '#{name}' in #{Array(template_directories).map{|d| File.expand_path(d) }}")
|
46
46
|
end
|
47
47
|
|
48
|
+
def template_name
|
49
|
+
name.underscore.sub(/_view$/,'')
|
50
|
+
end
|
51
|
+
|
48
52
|
def template(*args)
|
49
53
|
if args.empty?
|
50
|
-
@template ||=
|
54
|
+
@template ||= template_name
|
51
55
|
else
|
52
56
|
@template = args.first
|
53
57
|
end
|
data/lib/curtain/version.rb
CHANGED
data/lib/curtain.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
require 'active_support/core_ext'
|
2
|
+
require 'curtain/version'
|
2
3
|
require 'curtain/templating'
|
3
4
|
require 'curtain/rendering'
|
4
5
|
require 'curtain/variable_support'
|
5
|
-
require 'curtain/
|
6
|
+
require 'curtain/output_buffer'
|
7
|
+
require 'curtain/html_helpers'
|
8
|
+
require 'curtain/form_helpers'
|
9
|
+
require 'curtain/form_builder'
|
10
|
+
require 'curtain/caching'
|
6
11
|
|
7
12
|
module Curtain
|
8
13
|
|
@@ -11,6 +16,9 @@ module Curtain
|
|
11
16
|
include Curtain::Templating
|
12
17
|
include Curtain::Rendering
|
13
18
|
include Curtain::VariableSupport
|
19
|
+
include Curtain::HTMLHelpers
|
20
|
+
include Curtain::FormHelpers
|
21
|
+
include Curtain::Caching
|
14
22
|
end
|
15
23
|
end
|
16
24
|
|
@@ -18,10 +26,19 @@ module Curtain
|
|
18
26
|
include Curtain
|
19
27
|
|
20
28
|
def initialize(attrs={})
|
29
|
+
@output_buffer = Curtain::OutputBuffer.new
|
21
30
|
attrs.each do |k,v|
|
22
31
|
send("#{k}=", v)
|
23
32
|
end
|
24
33
|
end
|
34
|
+
|
35
|
+
def self.render(*args)
|
36
|
+
new.render(*args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.render(*args)
|
41
|
+
View.render(*args)
|
25
42
|
end
|
26
43
|
|
27
44
|
end
|
data/test/basic_test.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BasicTest < Curtain::TestCase
|
4
|
+
|
5
|
+
# Using the top-level to test default template name behavior
|
6
|
+
class ::TestView < Curtain::View
|
7
|
+
attr_accessor :name
|
8
|
+
|
9
|
+
def shout(s)
|
10
|
+
s.upcase
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class SubdirView < Curtain::View
|
15
|
+
template :index
|
16
|
+
end
|
17
|
+
|
18
|
+
def use(lang)
|
19
|
+
TestView.template_directories = File.join(File.dirname(__FILE__), "examples", "basic", lang)
|
20
|
+
|
21
|
+
SubdirView.template_directories = [
|
22
|
+
File.join(File.dirname(__FILE__), "examples", "basic", lang, "subdir"),
|
23
|
+
File.join(File.dirname(__FILE__), "examples", "basic", lang)
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
27
|
+
%w[erb slim].each do |lang|
|
28
|
+
test "render default with #{lang}" do
|
29
|
+
use lang
|
30
|
+
view = TestView.new
|
31
|
+
assert_equal "<h1>TEST</h1>", strip_lines(view.render)
|
32
|
+
end
|
33
|
+
|
34
|
+
test "render default with locals with #{lang}" do
|
35
|
+
use lang
|
36
|
+
view = TestView.new
|
37
|
+
assert_equal "<h1>TEST</h1><p>Hello, World!</p>", strip_lines(view.render(:msg => "Hello, World!"))
|
38
|
+
end
|
39
|
+
|
40
|
+
test "render template with #{lang}" do
|
41
|
+
use lang
|
42
|
+
view = TestView.new
|
43
|
+
assert_equal "<h1>default</h1>", strip_lines(view.render(:index))
|
44
|
+
end
|
45
|
+
|
46
|
+
test "render template with locals with #{lang}" do
|
47
|
+
use lang
|
48
|
+
view = TestView.new
|
49
|
+
assert_equal "<h1>Hello, World!</h1>", strip_lines(view.render(:index, :msg => "Hello, World!"))
|
50
|
+
end
|
51
|
+
|
52
|
+
test "variables and render within template with #{lang}" do
|
53
|
+
use lang
|
54
|
+
view = TestView.new
|
55
|
+
view[:msg] = "Hello, World!"
|
56
|
+
assert_equal "<html><body><h1>Hello, World!</h1></body></html>", strip_lines(view.render("layout", :main => "body"))
|
57
|
+
end
|
58
|
+
|
59
|
+
test "render multiple template directories with #{lang}" do
|
60
|
+
use lang
|
61
|
+
view = SubdirView.new
|
62
|
+
assert_equal "<h1>Subdir</h1>", strip_lines(view.render)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
data/test/cache_test.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CacheTest < Curtain::TestCase
|
4
|
+
class ::CacheView < Curtain::View
|
5
|
+
end
|
6
|
+
|
7
|
+
def use(lang)
|
8
|
+
CacheView.template_directories File.join(File.dirname(__FILE__), "examples", "cache", lang)
|
9
|
+
end
|
10
|
+
|
11
|
+
%w[erb slim].each do |lang|
|
12
|
+
test "cache with #{lang}" do
|
13
|
+
use lang
|
14
|
+
assert_equal %{<h1>Test</h1>}, strip_lines(CacheView.render)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1><%= defined?(msg) ? msg : 'default' %></h1>
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
h1= defined?(msg) ? msg : 'default'
|
@@ -0,0 +1 @@
|
|
1
|
+
h1 Subdir
|