papercraft 0.10.1 → 0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +52 -0
- data/lib/papercraft/renderer.rb +70 -1
- data/lib/papercraft/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3452d115d85742018d1497b369ea27970f0c144e3dcb1772f4d81e33315dce51
|
4
|
+
data.tar.gz: e7217a9d9bcfd7af0dc92482650bc03392b0406cf4f3d6141c253a2918638545
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f76b9e73aa48f91af932af3308d3dd43239c3d5ca39e305cb1535417b5997483aa884f0e34ed128800b07a3135ebc1d18ea81d0df64e6170726a66c86969288
|
7
|
+
data.tar.gz: dbe744ca25996c3d263ff609ca26f42076784fdbceabd2dd1604dd1016e2d840830230f4205a673b9e5ba14eb8e480627612971b71ca6631e0a6e473d59ccb73
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -374,6 +374,58 @@ The deafult options can be configured by accessing
|
|
374
374
|
Papercraft::HTML.kramdown_options[:auto_ids] = false
|
375
375
|
```
|
376
376
|
|
377
|
+
## Deferred evaluation
|
378
|
+
|
379
|
+
Deferred evaluation allows deferring the rendering of parts of a template until
|
380
|
+
the last moment, thus allowing an inner component to manipulate the state of the
|
381
|
+
outer component. To in order to defer a part of a template, use `#defer`, and
|
382
|
+
include any markup in the provided block. This technique, in in conjunction with
|
383
|
+
holding state in instance variables, is an alternative to passing parameters,
|
384
|
+
which can be limiting in some situations.
|
385
|
+
|
386
|
+
A few use cases for deferred evaulation come to mind:
|
387
|
+
|
388
|
+
- Setting the page title.
|
389
|
+
- Adding a flash message to a page.
|
390
|
+
- Using components that dynamically add static dependencies (JS and CSS) to the
|
391
|
+
page.
|
392
|
+
|
393
|
+
The last use case is particularly interesting. Imagine a `DependencyMananger`
|
394
|
+
class that can collect JS and CSS dependencies from the different components
|
395
|
+
integrated into the page, and adds them to the page's `<head>` element:
|
396
|
+
|
397
|
+
```ruby
|
398
|
+
default_layout = H { |**args|
|
399
|
+
@dependencies = DependencyMananger.new
|
400
|
+
head {
|
401
|
+
defer { emit @dependencies.head_markup }
|
402
|
+
}
|
403
|
+
body { emit_yield **args }
|
404
|
+
}
|
405
|
+
|
406
|
+
button = proc { |text, onclick|
|
407
|
+
@dependencies.js '/static/js/button.js'
|
408
|
+
@dependencies.css '/static/css/button.css'
|
409
|
+
|
410
|
+
button text, onclick: onclick
|
411
|
+
}
|
412
|
+
|
413
|
+
heading = proc { |text|
|
414
|
+
@dependencies.js '/static/js/heading.js'
|
415
|
+
@dependencies.css '/static/css/heading.css'
|
416
|
+
|
417
|
+
h1 text
|
418
|
+
}
|
419
|
+
|
420
|
+
page = default_layout.apply {
|
421
|
+
emit heading, "What's your favorite cheese?"
|
422
|
+
|
423
|
+
emit button, 'Beaufort', 'eat_beaufort()'
|
424
|
+
emit button, 'Mont d''or', 'eat_montdor()'
|
425
|
+
emit button, 'Époisses', 'eat_epoisses()'
|
426
|
+
}
|
427
|
+
```
|
428
|
+
|
377
429
|
## Papercraft extensions
|
378
430
|
|
379
431
|
Papercraft extensions are modules that contain one or more methods that can be
|
data/lib/papercraft/renderer.rb
CHANGED
@@ -57,12 +57,14 @@ module Papercraft
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
INITIAL_BUFFER_CAPACITY = 8192
|
61
|
+
|
60
62
|
# Initializes the renderer and evaulates the given template in the
|
61
63
|
# renderer's scope.
|
62
64
|
#
|
63
65
|
# @param &template [Proc] template block
|
64
66
|
def initialize(&template)
|
65
|
-
@buffer =
|
67
|
+
@buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
|
66
68
|
instance_eval(&template)
|
67
69
|
end
|
68
70
|
|
@@ -70,6 +72,20 @@ module Papercraft
|
|
70
72
|
#
|
71
73
|
# @return [String]
|
72
74
|
def to_s
|
75
|
+
if @parts
|
76
|
+
last = @buffer
|
77
|
+
@buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
|
78
|
+
parts = @parts
|
79
|
+
@parts = nil
|
80
|
+
parts.each do |p|
|
81
|
+
if Proc === p
|
82
|
+
render_deferred_proc(&p)
|
83
|
+
else
|
84
|
+
@buffer << p
|
85
|
+
end
|
86
|
+
end
|
87
|
+
@buffer << last unless last.empty?
|
88
|
+
end
|
73
89
|
@buffer
|
74
90
|
end
|
75
91
|
|
@@ -160,6 +176,42 @@ module Papercraft
|
|
160
176
|
|
161
177
|
instance_exec(*a, **b, &@inner_block)
|
162
178
|
end
|
179
|
+
|
180
|
+
# Defers the given block to be evaluated later. Deferred evaluation allows
|
181
|
+
# Papercraft components to inject state into sibling components, regardless
|
182
|
+
# of the component's order in the container component. For example, a nested
|
183
|
+
# component may set an instance variable used by another component. This is
|
184
|
+
# an elegant solution to the problem of setting the HTML page's title, or
|
185
|
+
# adding elements to the `<head>` section. Here's how a title can be
|
186
|
+
# controlled from a nested component:
|
187
|
+
#
|
188
|
+
# layout = H {
|
189
|
+
# html {
|
190
|
+
# head {
|
191
|
+
# defer { title @title }
|
192
|
+
# }
|
193
|
+
# body {
|
194
|
+
# emit_yield
|
195
|
+
# }
|
196
|
+
# }
|
197
|
+
# }
|
198
|
+
#
|
199
|
+
# html.render {
|
200
|
+
# @title = 'My super page'
|
201
|
+
# h1 'content'
|
202
|
+
# }
|
203
|
+
#
|
204
|
+
# @param &block [Proc] Deferred block to be emitted
|
205
|
+
# @return [void]
|
206
|
+
def defer(&block)
|
207
|
+
if !@parts
|
208
|
+
@parts = [@buffer, block]
|
209
|
+
else
|
210
|
+
@parts << @buffer unless @buffer.empty?
|
211
|
+
@parts << block
|
212
|
+
end
|
213
|
+
@buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
|
214
|
+
end
|
163
215
|
|
164
216
|
S_LT = '<'
|
165
217
|
S_GT = '>'
|
@@ -217,6 +269,23 @@ module Papercraft
|
|
217
269
|
end
|
218
270
|
}
|
219
271
|
end
|
272
|
+
|
273
|
+
# Renders a deferred proc by evaluating it, then adding the rendered result
|
274
|
+
# to the buffer.
|
275
|
+
#
|
276
|
+
# @param &block [Proc] deferred proc
|
277
|
+
# @return [void]
|
278
|
+
def render_deferred_proc(&block)
|
279
|
+
old_buffer = @buffer
|
280
|
+
|
281
|
+
@buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
|
282
|
+
@parts = nil
|
283
|
+
|
284
|
+
instance_eval(&block)
|
285
|
+
|
286
|
+
old_buffer << to_s
|
287
|
+
@buffer = old_buffer
|
288
|
+
end
|
220
289
|
end
|
221
290
|
|
222
291
|
# Implements an HTML renderer
|
data/lib/papercraft/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: papercraft
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.11'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: escape_utils
|
@@ -166,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
166
|
- !ruby/object:Gem::Version
|
167
167
|
version: '0'
|
168
168
|
requirements: []
|
169
|
-
rubygems_version: 3.
|
169
|
+
rubygems_version: 3.3.3
|
170
170
|
signing_key:
|
171
171
|
specification_version: 4
|
172
172
|
summary: 'Papercraft: component-based HTML templating for Ruby'
|