template_streaming 0.0.3 → 0.0.4
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/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
|