merb-core 0.9.8 → 0.9.9
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/CONTRIBUTORS +33 -0
- data/README +7 -3
- data/Rakefile +3 -3
- data/lib/merb-core.rb +165 -94
- data/lib/merb-core/bootloader.rb +469 -100
- data/lib/merb-core/config.rb +79 -3
- data/lib/merb-core/constants.rb +24 -2
- data/lib/merb-core/controller/abstract_controller.rb +172 -67
- data/lib/merb-core/controller/exceptions.rb +50 -6
- data/lib/merb-core/controller/merb_controller.rb +215 -108
- data/lib/merb-core/controller/mime.rb +36 -12
- data/lib/merb-core/controller/mixins/authentication.rb +52 -7
- data/lib/merb-core/controller/mixins/conditional_get.rb +14 -0
- data/lib/merb-core/controller/mixins/controller.rb +90 -58
- data/lib/merb-core/controller/mixins/render.rb +34 -10
- data/lib/merb-core/controller/mixins/responder.rb +40 -16
- data/lib/merb-core/controller/template.rb +37 -16
- data/lib/merb-core/core_ext/hash.rb +9 -0
- data/lib/merb-core/core_ext/kernel.rb +92 -41
- data/lib/merb-core/dispatch/dispatcher.rb +29 -45
- data/lib/merb-core/dispatch/request.rb +186 -82
- data/lib/merb-core/dispatch/router.rb +141 -53
- data/lib/merb-core/dispatch/router/behavior.rb +296 -139
- data/lib/merb-core/dispatch/router/resources.rb +51 -19
- data/lib/merb-core/dispatch/router/route.rb +76 -23
- data/lib/merb-core/dispatch/session.rb +80 -36
- data/lib/merb-core/dispatch/session/container.rb +31 -15
- data/lib/merb-core/dispatch/session/cookie.rb +51 -22
- data/lib/merb-core/dispatch/session/memcached.rb +10 -6
- data/lib/merb-core/dispatch/session/memory.rb +17 -5
- data/lib/merb-core/dispatch/session/store_container.rb +21 -9
- data/lib/merb-core/dispatch/worker.rb +16 -2
- data/lib/merb-core/gem_ext/erubis.rb +4 -0
- data/lib/merb-core/plugins.rb +13 -0
- data/lib/merb-core/rack.rb +1 -0
- data/lib/merb-core/rack/adapter.rb +1 -0
- data/lib/merb-core/rack/adapter/abstract.rb +95 -17
- data/lib/merb-core/rack/adapter/irb.rb +50 -5
- data/lib/merb-core/rack/application.rb +27 -5
- data/lib/merb-core/rack/handler/mongrel.rb +6 -6
- data/lib/merb-core/rack/helpers.rb +33 -0
- data/lib/merb-core/rack/middleware/conditional_get.rb +1 -1
- data/lib/merb-core/rack/middleware/path_prefix.rb +3 -3
- data/lib/merb-core/rack/middleware/static.rb +11 -7
- data/lib/merb-core/server.rb +134 -69
- data/lib/merb-core/tasks/gem_management.rb +153 -80
- data/lib/merb-core/tasks/merb_rake_helper.rb +12 -4
- data/lib/merb-core/tasks/stats.rake +1 -1
- data/lib/merb-core/test/helpers/mock_request_helper.rb +29 -22
- data/lib/merb-core/test/helpers/request_helper.rb +1 -1
- data/lib/merb-core/test/helpers/route_helper.rb +50 -4
- data/lib/merb-core/test/matchers/request_matchers.rb +2 -36
- data/lib/merb-core/test/matchers/view_matchers.rb +32 -22
- data/lib/merb-core/test/run_specs.rb +6 -5
- data/lib/merb-core/test/test_ext/rspec.rb +6 -19
- data/lib/merb-core/version.rb +1 -1
- metadata +5 -4
@@ -4,6 +4,8 @@ module Merb::RenderMixin
|
|
4
4
|
|
5
5
|
# ==== Parameters
|
6
6
|
# base<Module>:: Module that is including RenderMixin (probably a controller)
|
7
|
+
#
|
8
|
+
# @private
|
7
9
|
def self.included(base)
|
8
10
|
base.extend(ClassMethods)
|
9
11
|
base.class_eval do
|
@@ -17,6 +19,8 @@ module Merb::RenderMixin
|
|
17
19
|
#
|
18
20
|
# ==== Returns
|
19
21
|
# Hash:: An options hash
|
22
|
+
#
|
23
|
+
# @api public
|
20
24
|
def default_render_options
|
21
25
|
self._default_render_options ||= {}
|
22
26
|
end
|
@@ -25,6 +29,8 @@ module Merb::RenderMixin
|
|
25
29
|
#
|
26
30
|
# ==== Parameters
|
27
31
|
# opts<Hash>:: An options hash
|
32
|
+
#
|
33
|
+
# @api public
|
28
34
|
def render_options(opts)
|
29
35
|
self._default_render_options = opts
|
30
36
|
end
|
@@ -40,11 +46,18 @@ module Merb::RenderMixin
|
|
40
46
|
#
|
41
47
|
# ==== Returns
|
42
48
|
# Hash:: The default render options.
|
49
|
+
#
|
50
|
+
# @api public
|
43
51
|
def layout(layout)
|
44
52
|
self.default_render_options.update(:layout => (layout || false))
|
45
53
|
end
|
46
54
|
|
47
55
|
# Enable the default layout logic - reset the layout option.
|
56
|
+
#
|
57
|
+
# ==== Returns
|
58
|
+
# ~to_s:: The layout that was previously set.
|
59
|
+
#
|
60
|
+
# @api public
|
48
61
|
def default_layout
|
49
62
|
self.default_render_options.delete(:layout)
|
50
63
|
end
|
@@ -82,8 +95,8 @@ module Merb::RenderMixin
|
|
82
95
|
# ==== Alternatives
|
83
96
|
# If you pass a Hash as the first parameter, it will be moved to opts and
|
84
97
|
# "thing" will be the current action
|
85
|
-
|
86
|
-
# @public
|
98
|
+
#
|
99
|
+
# @api public
|
87
100
|
def render(thing = nil, opts = {})
|
88
101
|
# render :format => :xml means render nil, :format => :xml
|
89
102
|
opts, thing = thing, nil if thing.is_a?(Hash)
|
@@ -188,6 +201,7 @@ module Merb::RenderMixin
|
|
188
201
|
# The transformed object will not be used in a layout unless a :layout is
|
189
202
|
# explicitly passed in the opts.
|
190
203
|
#
|
204
|
+
# @api public
|
191
205
|
def display(object, thing = nil, opts = {})
|
192
206
|
template_opt = thing.is_a?(Hash) ? thing.delete(:template) : opts.delete(:template)
|
193
207
|
|
@@ -268,6 +282,8 @@ module Merb::RenderMixin
|
|
268
282
|
#
|
269
283
|
# In this case, "one" will be available in the partial through the local
|
270
284
|
# variable named +number+.
|
285
|
+
#
|
286
|
+
# @api public
|
271
287
|
def partial(template, opts={})
|
272
288
|
|
273
289
|
# partial :foo becomes "#{controller_name}/_foo"
|
@@ -323,6 +339,8 @@ module Merb::RenderMixin
|
|
323
339
|
#
|
324
340
|
# ==== Returns
|
325
341
|
# Hash:: The options hash that was passed in.
|
342
|
+
#
|
343
|
+
# @api private
|
326
344
|
def _handle_options!(opts)
|
327
345
|
self.status = opts.delete(:status).to_i if opts[:status]
|
328
346
|
headers["Location"] = opts.delete(:location) if opts[:location]
|
@@ -346,6 +364,8 @@ module Merb::RenderMixin
|
|
346
364
|
# If a layout was specified (either via layout in the class or by passing
|
347
365
|
# one in to this method), and not found. No error will be raised if no
|
348
366
|
# layout was specified, and the default layouts were not found.
|
367
|
+
#
|
368
|
+
# @api private
|
349
369
|
def _get_layout(layout = nil)
|
350
370
|
return false if layout == false
|
351
371
|
|
@@ -385,6 +405,8 @@ module Merb::RenderMixin
|
|
385
405
|
# ==== Returns
|
386
406
|
# Array[Symbol, String]::
|
387
407
|
# A pair consisting of the template method and location.
|
408
|
+
#
|
409
|
+
# @api private
|
388
410
|
def _template_for(context, content_type, controller=nil, template=nil, locals=[])
|
389
411
|
template_method, template_location = nil, nil
|
390
412
|
|
@@ -419,6 +441,8 @@ module Merb::RenderMixin
|
|
419
441
|
#
|
420
442
|
# ==== Returns
|
421
443
|
# String:: The method, if it exists. Otherwise return nil.
|
444
|
+
#
|
445
|
+
# @api private
|
422
446
|
def _template_method_for(template_location, locals)
|
423
447
|
meth = Merb::Template.template_for(template_location, [], locals)
|
424
448
|
meth && self.respond_to?(meth) ? meth : nil
|
@@ -431,8 +455,8 @@ module Merb::RenderMixin
|
|
431
455
|
#
|
432
456
|
# ==== Parameters
|
433
457
|
# obj<Object>:: The key in the thrown_content hash. Defaults to :for_layout.
|
434
|
-
|
435
|
-
# @public
|
458
|
+
#
|
459
|
+
# @api public
|
436
460
|
def catch_content(obj = :for_layout)
|
437
461
|
@_caught_content[obj] || ''
|
438
462
|
end
|
@@ -441,8 +465,8 @@ module Merb::RenderMixin
|
|
441
465
|
#
|
442
466
|
# ==== Parameters
|
443
467
|
# obj<Object>:: The key in the thrown_content hash. Defaults to :for_layout.
|
444
|
-
|
445
|
-
# @public
|
468
|
+
#
|
469
|
+
# @api public
|
446
470
|
def thrown_content?(obj = :for_layout)
|
447
471
|
@_caught_content.key?(obj)
|
448
472
|
end
|
@@ -463,8 +487,8 @@ module Merb::RenderMixin
|
|
463
487
|
# ==== Example
|
464
488
|
# throw_content(:foo, "Foo")
|
465
489
|
# catch_content(:foo) #=> "Foo"
|
466
|
-
|
467
|
-
# @public
|
490
|
+
#
|
491
|
+
# @api public
|
468
492
|
def throw_content(obj, string = nil, &block)
|
469
493
|
unless string || block_given?
|
470
494
|
raise ArgumentError, "You must pass a block or a string into throw_content"
|
@@ -499,8 +523,8 @@ module Merb::RenderMixin
|
|
499
523
|
#
|
500
524
|
# ==== Parameters
|
501
525
|
# obj<Object>:: The key in the thrown_content hash. Defaults to :for_layout.
|
502
|
-
|
503
|
-
# @public
|
526
|
+
#
|
527
|
+
# @api public
|
504
528
|
def clear_content(obj = :for_layout)
|
505
529
|
@_caught_content.delete(obj) unless @_caught_content[obj].nil?
|
506
530
|
end
|
@@ -104,6 +104,8 @@ module Merb
|
|
104
104
|
|
105
105
|
# ==== Parameters
|
106
106
|
# base<Module>:: The module that ResponderMixin was mixed into
|
107
|
+
#
|
108
|
+
# @api private
|
107
109
|
def self.included(base)
|
108
110
|
base.extend(ClassMethods)
|
109
111
|
base.class_eval do
|
@@ -130,8 +132,8 @@ module Merb
|
|
130
132
|
#
|
131
133
|
# ==== Examples
|
132
134
|
# provides :html, :xml
|
133
|
-
|
134
|
-
# @public
|
135
|
+
#
|
136
|
+
# @api public
|
135
137
|
def provides(*formats)
|
136
138
|
self.class_provided_formats |= formats
|
137
139
|
end
|
@@ -145,8 +147,7 @@ module Merb
|
|
145
147
|
# ==== Returns
|
146
148
|
# Array[Symbol]:: List of formats passed in.
|
147
149
|
#
|
148
|
-
|
149
|
-
# @public
|
150
|
+
# @api public
|
150
151
|
def only_provides(*formats)
|
151
152
|
clear_provides
|
152
153
|
provides(*formats)
|
@@ -162,8 +163,7 @@ module Merb
|
|
162
163
|
# Array[Symbol]::
|
163
164
|
# List of formats that remain after removing the ones not to provide.
|
164
165
|
#
|
165
|
-
|
166
|
-
# @public
|
166
|
+
# @api public
|
167
167
|
def does_not_provide(*formats)
|
168
168
|
self.class_provided_formats -= formats
|
169
169
|
end
|
@@ -172,6 +172,8 @@ module Merb
|
|
172
172
|
#
|
173
173
|
# ==== Returns
|
174
174
|
# Array:: An empty Array.
|
175
|
+
#
|
176
|
+
# @api public
|
175
177
|
def clear_provides
|
176
178
|
self.class_provided_formats.clear
|
177
179
|
end
|
@@ -180,6 +182,8 @@ module Merb
|
|
180
182
|
#
|
181
183
|
# ==== Returns
|
182
184
|
# Array[Symbol]:: [:html].
|
185
|
+
#
|
186
|
+
# @api public
|
183
187
|
def reset_provides
|
184
188
|
only_provides(:html)
|
185
189
|
end
|
@@ -190,6 +194,8 @@ module Merb
|
|
190
194
|
# The current list of formats provided for this instance of the
|
191
195
|
# controller. It starts with what has been set in the controller (or
|
192
196
|
# :html by default) but can be modifed on a per-action basis.
|
197
|
+
#
|
198
|
+
# @api private
|
193
199
|
def _provided_formats
|
194
200
|
@_provided_formats ||= class_provided_formats.dup
|
195
201
|
end
|
@@ -209,8 +215,7 @@ module Merb
|
|
209
215
|
# ==== Returns
|
210
216
|
# Array[Symbol]:: List of formats passed in.
|
211
217
|
#
|
212
|
-
|
213
|
-
# @public
|
218
|
+
# @api public
|
214
219
|
def provides(*formats)
|
215
220
|
if @_content_type
|
216
221
|
raise ContentTypeAlreadySet, "Cannot modify provided_formats because content_type has already been set"
|
@@ -229,8 +234,7 @@ module Merb
|
|
229
234
|
# ==== Returns
|
230
235
|
# Array[Symbol]:: List of formats passed in.
|
231
236
|
#
|
232
|
-
|
233
|
-
# @public
|
237
|
+
# @api public
|
234
238
|
def only_provides(*formats)
|
235
239
|
@_provided_formats = []
|
236
240
|
provides(*formats)
|
@@ -248,8 +252,7 @@ module Merb
|
|
248
252
|
# Array[Symbol]::
|
249
253
|
# List of formats that remain after removing the ones not to provide.
|
250
254
|
#
|
251
|
-
|
252
|
-
# @public
|
255
|
+
# @api public
|
253
256
|
def does_not_provide(*formats)
|
254
257
|
@_provided_formats -= formats.flatten
|
255
258
|
end
|
@@ -260,6 +263,8 @@ module Merb
|
|
260
263
|
# 3. If it's */*, use the first provided format
|
261
264
|
# 4. Look for one that is provided, in order of request
|
262
265
|
# 5. Raise 406 if none found
|
266
|
+
#
|
267
|
+
# @api private
|
263
268
|
def _perform_content_negotiation
|
264
269
|
if (fmt = params[:format]) && !fmt.empty?
|
265
270
|
accepts = [fmt.to_sym]
|
@@ -307,8 +312,7 @@ module Merb
|
|
307
312
|
# ==== Returns
|
308
313
|
# Symbol:: The content-type that will be used for this controller.
|
309
314
|
#
|
310
|
-
|
311
|
-
# @public
|
315
|
+
# @api public
|
312
316
|
def content_type(fmt = nil)
|
313
317
|
self.content_type = (fmt || _perform_content_negotiation) unless @_content_type
|
314
318
|
@_content_type
|
@@ -327,8 +331,7 @@ module Merb
|
|
327
331
|
# ==== Returns
|
328
332
|
# Symbol:: The content-type that was passed in.
|
329
333
|
#
|
330
|
-
|
331
|
-
# @semipublic
|
334
|
+
# @api plugin
|
332
335
|
def content_type=(type)
|
333
336
|
unless Merb.available_mime_types.has_key?(type)
|
334
337
|
raise Merb::ControllerExceptions::NotAcceptable.new("Unknown content_type for response: #{type}")
|
@@ -359,6 +362,8 @@ module Merb
|
|
359
362
|
#
|
360
363
|
# ==== Returns
|
361
364
|
# Array[AcceptType]:: The accepted types.
|
365
|
+
#
|
366
|
+
# @private
|
362
367
|
def self.parse(accept_header)
|
363
368
|
headers = accept_header.split(/,/)
|
364
369
|
idx, list = 0, []
|
@@ -378,6 +383,8 @@ module Merb
|
|
378
383
|
# index<Fixnum>::
|
379
384
|
# The index used for sorting accept types. A lower value indicates higher
|
380
385
|
# priority.
|
386
|
+
#
|
387
|
+
# @api private
|
381
388
|
def initialize(entry,index)
|
382
389
|
@index = index
|
383
390
|
|
@@ -399,6 +406,8 @@ module Merb
|
|
399
406
|
# Fixnum::
|
400
407
|
# -1, 0 or 1, depending on whether entry has a lower, equal or higher
|
401
408
|
# priority than the accept type being compared.
|
409
|
+
#
|
410
|
+
# @api private
|
402
411
|
def <=>(entry)
|
403
412
|
if entry.quality == quality
|
404
413
|
@index <=> entry.index
|
@@ -415,20 +424,28 @@ module Merb
|
|
415
424
|
# Boolean::
|
416
425
|
# True if the accept types are equal, i.e. if the synonyms for this
|
417
426
|
# accept type includes the entry media range.
|
427
|
+
#
|
428
|
+
# @api private
|
418
429
|
def eql?(entry)
|
419
430
|
synonyms.include?(entry.media_range)
|
420
431
|
end
|
421
432
|
|
422
433
|
# An alias for eql?.
|
434
|
+
#
|
435
|
+
# @api private
|
423
436
|
def ==(entry); eql?(entry); end
|
424
437
|
|
425
438
|
# ==== Returns
|
426
439
|
# Fixnum:: A hash based on the super range.
|
440
|
+
#
|
441
|
+
# @api private
|
427
442
|
def hash; super_range.hash; end
|
428
443
|
|
429
444
|
# ==== Returns
|
430
445
|
# Array[String]::
|
431
446
|
# All Accept header values, such as "text/html", that match this type.
|
447
|
+
#
|
448
|
+
# @api private
|
432
449
|
def synonyms
|
433
450
|
return @syns if @syns
|
434
451
|
if _mime = mime
|
@@ -438,6 +455,7 @@ module Merb
|
|
438
455
|
end
|
439
456
|
end
|
440
457
|
|
458
|
+
# @api private
|
441
459
|
def mime
|
442
460
|
@mime ||= Merb.available_mime_types[Merb::ResponderMixin::MIMES[@media_range]]
|
443
461
|
end
|
@@ -446,12 +464,16 @@ module Merb
|
|
446
464
|
# String::
|
447
465
|
# The primary media range for this accept type, i.e. either the first
|
448
466
|
# synonym or, if none exist, the media range.
|
467
|
+
#
|
468
|
+
# @api private
|
449
469
|
def super_range
|
450
470
|
synonyms.first || @media_range
|
451
471
|
end
|
452
472
|
|
453
473
|
# ==== Returns
|
454
474
|
# Symbol: The type as a symbol, e.g. :html.
|
475
|
+
#
|
476
|
+
# @api private
|
455
477
|
def to_sym
|
456
478
|
Merb.available_mime_types.select{|k,v|
|
457
479
|
v[:accepts] == synonyms || v[:accepts][0] == synonyms[0]}.flatten.first
|
@@ -459,6 +481,8 @@ module Merb
|
|
459
481
|
|
460
482
|
# ==== Returns
|
461
483
|
# String:: The accept type as a string, i.e. the media range.
|
484
|
+
#
|
485
|
+
# @api private
|
462
486
|
def to_s
|
463
487
|
@media_range
|
464
488
|
end
|
@@ -21,10 +21,12 @@ module Merb::Template
|
|
21
21
|
# ==== Returns
|
22
22
|
# String:: The template name.
|
23
23
|
#
|
24
|
-
|
24
|
+
#
|
25
25
|
# We might want to replace this with something that varies the
|
26
26
|
# character replaced based on the non-alphanumeric character
|
27
27
|
# to avoid edge-case collisions.
|
28
|
+
#
|
29
|
+
# @api private
|
28
30
|
def template_name(path)
|
29
31
|
path = File.expand_path(path)
|
30
32
|
path.gsub(/[^\.a-zA-Z0-9]/, "__").gsub(/\./, "_")
|
@@ -45,8 +47,9 @@ module Merb::Template
|
|
45
47
|
#
|
46
48
|
# ==== Returns
|
47
49
|
# IO#path:: An IO object that responds to path (File or VirtualFile).
|
48
|
-
|
49
|
-
# @
|
50
|
+
#
|
51
|
+
# @api plugin
|
52
|
+
# @overridable
|
50
53
|
def load_template_io(path)
|
51
54
|
File.open(path, "r")
|
52
55
|
end
|
@@ -60,8 +63,8 @@ module Merb::Template
|
|
60
63
|
#
|
61
64
|
# ==== Returns
|
62
65
|
# <String>:: name of the method that inlines the template.
|
63
|
-
|
64
|
-
# @
|
66
|
+
#
|
67
|
+
# @api private
|
65
68
|
def template_for(path, template_stack = [], locals=[])
|
66
69
|
path = File.expand_path(path)
|
67
70
|
|
@@ -81,20 +84,22 @@ module Merb::Template
|
|
81
84
|
#
|
82
85
|
# ==== Returns
|
83
86
|
# Boolean:: Whether or not the template for the provided path needs to be recompiled
|
84
|
-
|
87
|
+
#
|
88
|
+
# @api private
|
85
89
|
def needs_compilation?(path, locals)
|
86
90
|
return true if Merb::Config[:reload_templates] || !METHOD_LIST[path]
|
87
91
|
|
88
92
|
current_locals = SUPPORTED_LOCALS_LIST[path]
|
89
|
-
locals
|
93
|
+
current_locals != locals &&
|
94
|
+
!(locals - current_locals).empty?
|
90
95
|
end
|
91
96
|
|
92
97
|
# Get all known template extensions
|
93
98
|
#
|
94
99
|
# ==== Returns
|
95
100
|
# Array:: Extension strings.
|
96
|
-
|
97
|
-
# @
|
101
|
+
#
|
102
|
+
# @api plugin
|
98
103
|
def template_extensions
|
99
104
|
EXTENSIONS.keys
|
100
105
|
end
|
@@ -112,11 +117,14 @@ module Merb::Template
|
|
112
117
|
# The module to put the compiled method into. Defaults to
|
113
118
|
# Merb::InlineTemplates
|
114
119
|
#
|
120
|
+
# ==== Returns
|
121
|
+
# Symbol:: The name of the method that the template was compiled into.
|
122
|
+
#
|
115
123
|
# ==== Notes
|
116
124
|
# Even though this method supports inlining into any module, the method
|
117
125
|
# must be available to instances of AbstractController that will use it.
|
118
|
-
|
119
|
-
# @
|
126
|
+
#
|
127
|
+
# @api private
|
120
128
|
def inline_template(io, locals=[], mod = Merb::InlineTemplates)
|
121
129
|
full_file_path = File.expand_path(io.path)
|
122
130
|
engine_neutral_path = full_file_path.gsub(/\.[^\.]*$/, "")
|
@@ -136,8 +144,8 @@ module Merb::Template
|
|
136
144
|
#
|
137
145
|
# ==== Returns
|
138
146
|
# Class:: The engine.
|
139
|
-
|
140
|
-
# @
|
147
|
+
#
|
148
|
+
# @api private
|
141
149
|
def engine_for(path)
|
142
150
|
path = File.expand_path(path)
|
143
151
|
EXTENSIONS[path.match(/\.([^\.]*)$/)[1]]
|
@@ -155,10 +163,13 @@ module Merb::Template
|
|
155
163
|
# ==== Raises
|
156
164
|
# ArgumentError:: engine does not have a compile_template method.
|
157
165
|
#
|
166
|
+
# ==== Returns
|
167
|
+
# nil
|
168
|
+
#
|
158
169
|
# ==== Example
|
159
170
|
# Merb::Template.register_extensions(Merb::Template::Erubis, ["erb"])
|
160
|
-
|
161
|
-
# @
|
171
|
+
#
|
172
|
+
# @api plugin
|
162
173
|
def register_extensions(engine, extensions)
|
163
174
|
raise ArgumentError, "The class you are registering does not have a compile_template method" unless
|
164
175
|
engine.respond_to?(:compile_template)
|
@@ -177,6 +188,8 @@ module Merb::Template
|
|
177
188
|
# name<String>:: The name of the method that will be created.
|
178
189
|
# locals<Array[Symbol]>:: A list of locals to assign from the args passed into the compiled template.
|
179
190
|
# mod<Module>:: The module that the compiled method will be placed into.
|
191
|
+
#
|
192
|
+
# @api private
|
180
193
|
def self.compile_template(io, name, locals, mod)
|
181
194
|
template = ::Erubis::BlockAwareEruby.new(io.read)
|
182
195
|
_old_verbose, $VERBOSE = $VERBOSE, nil
|
@@ -206,6 +219,8 @@ module Merb::Template
|
|
206
219
|
# <% @foo = capture do %>
|
207
220
|
# <p>Some Foo content!</p>
|
208
221
|
# <% end %>
|
222
|
+
#
|
223
|
+
# @private
|
209
224
|
def capture_erb(*args, &block)
|
210
225
|
_old_buf, @_erb_buf = @_erb_buf, ""
|
211
226
|
block.call(*args)
|
@@ -214,7 +229,7 @@ module Merb::Template
|
|
214
229
|
ret
|
215
230
|
end
|
216
231
|
|
217
|
-
#
|
232
|
+
# @private
|
218
233
|
def concat_erb(string, binding)
|
219
234
|
@_erb_buf << string
|
220
235
|
end
|
@@ -228,30 +243,36 @@ end
|
|
228
243
|
|
229
244
|
module Erubis
|
230
245
|
module BlockAwareEnhancer
|
246
|
+
# @api private
|
231
247
|
def add_preamble(src)
|
232
248
|
src << "_old_buf, @_erb_buf = @_erb_buf, ''; "
|
233
249
|
src << "@_engine = 'erb'; "
|
234
250
|
end
|
235
251
|
|
252
|
+
# @api private
|
236
253
|
def add_postamble(src)
|
237
254
|
src << "\n" unless src[-1] == ?\n
|
238
255
|
src << "_ret = @_erb_buf; @_erb_buf = _old_buf; _ret.to_s;\n"
|
239
256
|
end
|
240
257
|
|
258
|
+
# @api private
|
241
259
|
def add_text(src, text)
|
242
260
|
src << " @_erb_buf.concat('" << escape_text(text) << "'); "
|
243
261
|
end
|
244
262
|
|
263
|
+
# @api private
|
245
264
|
def add_expr_escaped(src, code)
|
246
265
|
src << ' @_erb_buf.concat(' << escaped_expr(code) << ');'
|
247
266
|
end
|
248
267
|
|
268
|
+
# @api private
|
249
269
|
def add_stmt2(src, code, tailch)
|
250
270
|
src << code
|
251
271
|
src << " ).to_s; " if tailch == "="
|
252
272
|
src << ';' unless code[-1] == ?\n
|
253
273
|
end
|
254
274
|
|
275
|
+
# @api private
|
255
276
|
def add_expr_literal(src, code)
|
256
277
|
if code =~ /(do|\{)(\s*\|[^|]*\|)?\s*\Z/
|
257
278
|
src << ' @_erb_buf.concat( ' << code << "; "
|