template_streaming 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -0
- data/README.markdown +41 -5
- data/lib/template_streaming.rb +43 -2
- data/lib/template_streaming/version.rb +9 -1
- metadata +3 -3
data/CHANGELOG
CHANGED
data/README.markdown
CHANGED
@@ -33,14 +33,50 @@ profiles that look more like:
|
|
33
33
|
|
34
34
|
![Progressive Rendering Profile][fast-profile]
|
35
35
|
|
36
|
-
Also provided is a `#push(data)` method which can be used to send extra tags to
|
37
|
-
the client as their need becomes apparent. For instance, you may wish to `push`
|
38
|
-
out a stylesheet link tag only if a particular partial is reached which contains
|
39
|
-
a complex widget.
|
40
|
-
|
41
36
|
[slow-profile]: http://github.com/oggy/template_streaming/raw/master/doc/slow-profile.png
|
42
37
|
[fast-profile]: http://github.com/oggy/template_streaming/raw/master/doc/fast-profile.png
|
43
38
|
|
39
|
+
## API
|
40
|
+
|
41
|
+
The API is simple, but it's important to understand the change in control flow
|
42
|
+
when a template is streamed. A controller's `render` no longer results in
|
43
|
+
rendering templates immediately; instead, `response.body` is set to a
|
44
|
+
`StreamingBody` object which will render the template when the server calls
|
45
|
+
`#each` on the body *after* the action returns, as per the Rack specification.
|
46
|
+
This has several implications:
|
47
|
+
|
48
|
+
* Anything that needs to inspect or modify the body should be moved to a
|
49
|
+
middleware.
|
50
|
+
* Modifications to cookies (this includes the flash and session if using the
|
51
|
+
cookie store!) should not be made in the view.
|
52
|
+
* An exception during rendering cannot simply replace the body with a
|
53
|
+
stacktrace or 500 page. (Solution to come.)
|
54
|
+
|
55
|
+
### Helpers
|
56
|
+
|
57
|
+
* `flush` - flush what has been rendered in the current template out to the
|
58
|
+
client immediately.
|
59
|
+
* `push(data)` - send the given data to the client immediately.
|
60
|
+
|
61
|
+
These can only do their job if the underlying web server supports progressive
|
62
|
+
rendering via Rack. This has been tested successfully with [Mongrel][mongrel]
|
63
|
+
and [Passenger][passenger]. [Thin][thin] is only supported if the [Event Machine
|
64
|
+
Flush][event-machine-flush] gem is installed. WEBrick does not support
|
65
|
+
progressive rendering. [Please send me][contact] reports of success with other
|
66
|
+
web servers!
|
67
|
+
|
68
|
+
[mongrel]: http://github.com/fauna/mongrel
|
69
|
+
[passenger]: http://www.modrails.com
|
70
|
+
[thin]: http://github.com/macournoyer/thin
|
71
|
+
[event-machine-flush]: http://github.com/oggy/event_machine_flush
|
72
|
+
[contact]: mailto:george.ogata@gmail.com
|
73
|
+
|
74
|
+
### Controller
|
75
|
+
|
76
|
+
* `when_streaming_template` - defines a callback to be called during a `render`
|
77
|
+
call when a template is streamed. This is *before* the body is rendered, or
|
78
|
+
any data is sent to the client.
|
79
|
+
|
44
80
|
## Example
|
45
81
|
|
46
82
|
Conventional wisdom says to put your external stylesheets in the HEAD of your
|
data/lib/template_streaming.rb
CHANGED
@@ -1,8 +1,25 @@
|
|
1
1
|
module TemplateStreaming
|
2
|
+
class << self
|
3
|
+
def configure(config)
|
4
|
+
config.each do |key, value|
|
5
|
+
send "#{key}=", value
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :autosweep_flash
|
10
|
+
end
|
11
|
+
|
12
|
+
self.autosweep_flash = true
|
13
|
+
|
2
14
|
module Controller
|
3
15
|
def self.included(base)
|
4
|
-
base.
|
5
|
-
|
16
|
+
base.class_eval do
|
17
|
+
alias_method_chain :render, :template_streaming
|
18
|
+
helper_method :flush, :push
|
19
|
+
|
20
|
+
include ActiveSupport::Callbacks
|
21
|
+
define_callbacks :when_streaming_template
|
22
|
+
end
|
6
23
|
end
|
7
24
|
|
8
25
|
def render_with_template_streaming(*args, &block)
|
@@ -19,6 +36,20 @@ module TemplateStreaming
|
|
19
36
|
end
|
20
37
|
response.body = @streaming_body
|
21
38
|
response.prepare!
|
39
|
+
flash if TemplateStreaming.autosweep_flash
|
40
|
+
run_callbacks :when_streaming_template
|
41
|
+
|
42
|
+
# Normally, @_flash is removed after #perform_action, which
|
43
|
+
# means calling #flash in the view would cause a new
|
44
|
+
# FlashHash to be constructed. On top of that, the flash is
|
45
|
+
# swept on construction, which results in sweeping the flash
|
46
|
+
# twice, obliterating its contents.
|
47
|
+
#
|
48
|
+
# So, we preserve the flash here under a different ivar, and
|
49
|
+
# override the #flash helper to return it.
|
50
|
+
if defined?(@_flash)
|
51
|
+
@template_streaming_flash = @_flash
|
52
|
+
end
|
22
53
|
else
|
23
54
|
render_without_template_streaming(*args, &block)
|
24
55
|
end
|
@@ -43,6 +74,10 @@ module TemplateStreaming
|
|
43
74
|
flush_thin
|
44
75
|
end
|
45
76
|
|
77
|
+
def template_streaming_flash # :nodoc:
|
78
|
+
@template_streaming_flash
|
79
|
+
end
|
80
|
+
|
46
81
|
private # --------------------------------------------------------
|
47
82
|
|
48
83
|
#
|
@@ -136,6 +171,7 @@ module TemplateStreaming
|
|
136
171
|
module View
|
137
172
|
def self.included(base)
|
138
173
|
base.alias_method_chain :_render_with_layout, :template_streaming
|
174
|
+
base.alias_method_chain :flash, :template_streaming
|
139
175
|
end
|
140
176
|
|
141
177
|
def _render_with_layout_with_template_streaming(options, local_assigns, &block)
|
@@ -177,6 +213,11 @@ module TemplateStreaming
|
|
177
213
|
view_paths.find_template('pre' + layout.path_without_format_and_extension, layout.format)
|
178
214
|
rescue ActionView::MissingTemplate
|
179
215
|
end
|
216
|
+
|
217
|
+
def flash_with_template_streaming # :nodoc:
|
218
|
+
# Override ActionView::Base#flash to prevent a double-sweep.
|
219
|
+
controller.instance_eval { @template_streaming_flash || flash }
|
220
|
+
end
|
180
221
|
end
|
181
222
|
|
182
223
|
class StreamingBody
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 4
|
9
|
+
version: 0.0.4
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- George Ogata
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-04-
|
17
|
+
date: 2010-04-26 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|