papercraft 0.10.1 → 0.11
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/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'
|