papercraft 0.18 → 0.19
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 +23 -23
- data/lib/papercraft/renderer.rb +4 -4
- data/lib/papercraft/{component.rb → template.rb} +26 -26
- data/lib/papercraft/version.rb +1 -1
- data/lib/papercraft.rb +17 -17
- data/papercraft.png +0 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0f4910bd26625ca0349b1c471338fb4d13e8055e88367b5cad16f91cdee7531
|
4
|
+
data.tar.gz: 38e43978278ba069e3767abd94d83c676f42692f5eb55f1be4b4067fae2f935e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b096452cebe7b6bb34a428f4920a5940e5b745c86b54188a984a77df6175145cf6645753e6ae58b3df89813919920a17a96610e010724bc50077c6f9accc7293
|
7
|
+
data.tar.gz: 8d1cd5b2d6b70ee9ef0a748a064bbd6d1630cfa926663aded95a01c26ce289a159e2548068bf8210c5e8d37ba26c9671eb4a00fe4790a47bec6dd822b4de5d5d
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -70,7 +70,7 @@ hello.render('world')
|
|
70
70
|
- [Plain procs as templates](#plain-procs-as-templates)
|
71
71
|
- [Template composition](#template-composition)
|
72
72
|
- [Parameter and block application](#parameter-and-block-application)
|
73
|
-
- [Higher-order
|
73
|
+
- [Higher-order templates](#higher-order-templates)
|
74
74
|
- [Layout template composition](#layout-template-composition)
|
75
75
|
- [Emitting raw HTML](#emitting-raw-html)
|
76
76
|
- [Emitting a string with HTML Encoding](#emitting-a-string-with-html-encoding)
|
@@ -221,8 +221,8 @@ Papercraft.html(&greeting).render('world')
|
|
221
221
|
|
222
222
|
## Template composition
|
223
223
|
|
224
|
-
Papercraft makes it easy to compose multiple
|
225
|
-
document. A Papercraft
|
224
|
+
Papercraft makes it easy to compose multiple templates into a whole HTML
|
225
|
+
document. A Papercraft template can contain other templates, as the following
|
226
226
|
example shows.
|
227
227
|
|
228
228
|
```ruby
|
@@ -250,14 +250,14 @@ page = Papercraft.html { |title, items|
|
|
250
250
|
}
|
251
251
|
}
|
252
252
|
|
253
|
-
page.render('Hello from
|
253
|
+
page.render('Hello from composed templates', [
|
254
254
|
{ id: 1, text: 'foo', checked: false },
|
255
255
|
{ id: 2, text: 'bar', checked: true }
|
256
256
|
])
|
257
257
|
```
|
258
258
|
|
259
|
-
In addition to using
|
260
|
-
non-constant
|
259
|
+
In addition to using templates defined as constants, you can also use
|
260
|
+
non-constant templates by invoking the `#emit` method:
|
261
261
|
|
262
262
|
```ruby
|
263
263
|
greeting = -> { span "Hello, world" }
|
@@ -272,11 +272,11 @@ Papercraft.html {
|
|
272
272
|
## Parameter and block application
|
273
273
|
|
274
274
|
Parameters and blocks can be applied to a template without it being rendered, by
|
275
|
-
using `#apply`. This mechanism is what allows
|
276
|
-
creation of higher-order
|
275
|
+
using `#apply`. This mechanism is what allows template composition and the
|
276
|
+
creation of higher-order templates.
|
277
277
|
|
278
|
-
The `#apply` method returns a new
|
279
|
-
or block to the original
|
278
|
+
The `#apply` method returns a new template which applies the given parameters and
|
279
|
+
or block to the original template:
|
280
280
|
|
281
281
|
```ruby
|
282
282
|
# parameter application
|
@@ -289,19 +289,19 @@ div_wrap = Papercraft.html { div { emit_yield } }
|
|
289
289
|
wrapped_h1 = div_wrap.apply { h1 'hi' }
|
290
290
|
wrapped_h1.render #=> "<div><h1>hi</h1></div>"
|
291
291
|
|
292
|
-
# wrap a
|
292
|
+
# wrap a template
|
293
293
|
wrapped_hello_world = div_wrap.apply(&hello_world)
|
294
294
|
wrapped_hello_world.render #=> "<div><h1>Hello, world!</h1></div>"
|
295
295
|
```
|
296
296
|
|
297
|
-
## Higher-order
|
297
|
+
## Higher-order templates
|
298
298
|
|
299
|
-
Papercraft also lets you create higher-order
|
300
|
-
|
301
|
-
|
302
|
-
markup, enhancing
|
299
|
+
Papercraft also lets you create higher-order templates, that is,
|
300
|
+
templates that take other templates as parameters, or as blocks. Higher-order
|
301
|
+
templates are handy for creating layouts, wrapping templates in arbitrary
|
302
|
+
markup, enhancing templates or injecting template parameters.
|
303
303
|
|
304
|
-
Here is a
|
304
|
+
Here is a higher-order template that takes a template as parameter:
|
305
305
|
|
306
306
|
```ruby
|
307
307
|
div_wrap = Papercraft.html { |inner| div { emit inner } }
|
@@ -310,7 +310,7 @@ wrapped_greeter = div_wrap.apply(greeter)
|
|
310
310
|
wrapped_greeter.render #=> "<div><h1>hi</h1></div>"
|
311
311
|
```
|
312
312
|
|
313
|
-
The inner
|
313
|
+
The inner template can also be passed as a block, as shown above:
|
314
314
|
|
315
315
|
```ruby
|
316
316
|
div_wrap = Papercraft.html { div { emit_yield } }
|
@@ -320,7 +320,7 @@ wrapped_greeter.render #=> "<div><h1>hi</h1></div>"
|
|
320
320
|
|
321
321
|
## Layout template composition
|
322
322
|
|
323
|
-
One of the principal uses of higher-order
|
323
|
+
One of the principal uses of higher-order templates is the creation of nested
|
324
324
|
layouts. Suppose we have a website with a number of different layouts, and we'd
|
325
325
|
like to avoid having to repeat the same code in the different layouts. We can do
|
326
326
|
this by creating a `default` page template that takes a block, then use `#apply`
|
@@ -434,8 +434,8 @@ end
|
|
434
434
|
## Deferred evaluation
|
435
435
|
|
436
436
|
Deferred evaluation allows deferring the rendering of parts of a template until
|
437
|
-
the last moment, thus allowing an inner
|
438
|
-
outer
|
437
|
+
the last moment, thus allowing an inner template to manipulate the state of the
|
438
|
+
outer template. To in order to defer a part of a template, use `#defer`, and
|
439
439
|
include any markup in the provided block. This technique, in in conjunction with
|
440
440
|
holding state in instance variables, is an alternative to passing parameters,
|
441
441
|
which can be limiting in some situations.
|
@@ -444,11 +444,11 @@ A few use cases for deferred evaulation come to mind:
|
|
444
444
|
|
445
445
|
- Setting the page title.
|
446
446
|
- Adding a flash message to a page.
|
447
|
-
- Using
|
447
|
+
- Using templates that dynamically add static dependencies (JS and CSS) to the
|
448
448
|
page.
|
449
449
|
|
450
450
|
The last use case is particularly interesting. Imagine a `DependencyMananger`
|
451
|
-
class that can collect JS and CSS dependencies from the different
|
451
|
+
class that can collect JS and CSS dependencies from the different templates
|
452
452
|
integrated into the page, and adds them to the page's `<head>` element:
|
453
453
|
|
454
454
|
```ruby
|
data/lib/papercraft/renderer.rb
CHANGED
@@ -8,7 +8,7 @@ require_relative './extension_proxy'
|
|
8
8
|
|
9
9
|
module Papercraft
|
10
10
|
|
11
|
-
# A Renderer renders a Papercraft
|
11
|
+
# A Renderer renders a Papercraft template into a string
|
12
12
|
class Renderer
|
13
13
|
|
14
14
|
class << self
|
@@ -43,7 +43,7 @@ module Papercraft
|
|
43
43
|
#
|
44
44
|
# Installs the given extensions, passed in the form of a Ruby hash mapping
|
45
45
|
# methods to extension modules. The methods will be available to all
|
46
|
-
# Papercraft
|
46
|
+
# Papercraft templates. Extension methods are executed in the context of
|
47
47
|
# the the renderer instance, so they can look just like normal proc
|
48
48
|
# components. In cases where method names in the module clash with HTML
|
49
49
|
# tag names, you can use the `#tag` method to emit the relevant tag.
|
@@ -219,7 +219,7 @@ module Papercraft
|
|
219
219
|
#
|
220
220
|
# Papercraft.html { emit nil }.render #=> ""
|
221
221
|
#
|
222
|
-
# @param o [Proc, Papercraft::
|
222
|
+
# @param o [Proc, Papercraft::Template, String] emitted object
|
223
223
|
# @param *a [Array<any>] arguments to pass to a proc
|
224
224
|
# @param **b [Hash] named arguments to pass to a proc
|
225
225
|
# @return [void]
|
@@ -253,7 +253,7 @@ module Papercraft
|
|
253
253
|
end
|
254
254
|
|
255
255
|
# Defers the given block to be evaluated later. Deferred evaluation allows
|
256
|
-
# Papercraft
|
256
|
+
# Papercraft templates to inject state into sibling components, regardless
|
257
257
|
# of the component's order in the container component. For example, a nested
|
258
258
|
# component may set an instance variable used by another component. This is
|
259
259
|
# an elegant solution to the problem of setting the HTML page's title, or
|
@@ -4,30 +4,30 @@ require_relative './html'
|
|
4
4
|
|
5
5
|
module Papercraft
|
6
6
|
|
7
|
-
#
|
8
|
-
# include other
|
7
|
+
# Template represents a distinct, reusable HTML template. A template can
|
8
|
+
# include other templates, and also be nested inside other templates.
|
9
9
|
#
|
10
|
-
# Since in Papercraft HTML is expressed using blocks (or procs,) the
|
10
|
+
# Since in Papercraft HTML is expressed using blocks (or procs,) the Template
|
11
11
|
# class is simply a special kind of Proc, which has some enhanced
|
12
12
|
# capabilities, allowing it to be easily composed in a variety of ways.
|
13
13
|
#
|
14
|
-
#
|
14
|
+
# Templates are usually created using the class methods `html`, `xml` or
|
15
15
|
# `json`, for HTML, XML or JSON templates, respectively:
|
16
16
|
#
|
17
17
|
# greeter = Papercraft.html { |name| h1 "Hello, #{name}!" }
|
18
18
|
# greeter.render('world') #=> "<h1>Hello, world!</h1>"
|
19
19
|
#
|
20
|
-
#
|
20
|
+
# Templates can also be created using the normal constructor:
|
21
21
|
#
|
22
|
-
# greeter = Papercraft::
|
22
|
+
# greeter = Papercraft::Template.new(mode: :html) { |name| h1 "Hello, #{name}!" }
|
23
23
|
# greeter.render('world') #=> "<h1>Hello, world!</h1>"
|
24
24
|
#
|
25
|
-
# The different methods for creating
|
25
|
+
# The different methods for creating templates can also take a custom MIME
|
26
26
|
# type, by passing a `mime_type` named argument:
|
27
27
|
#
|
28
28
|
# json = Papercraft.json(mime_type: 'application/feed+json') { ... }
|
29
29
|
#
|
30
|
-
# In the
|
30
|
+
# In the template block, HTML elements are created by simply calling
|
31
31
|
# unqualified methods:
|
32
32
|
#
|
33
33
|
# page_layout = Papercraft.html {
|
@@ -41,20 +41,20 @@ module Papercraft
|
|
41
41
|
# }
|
42
42
|
# }
|
43
43
|
#
|
44
|
-
# Papercraft
|
44
|
+
# Papercraft templates can take explicit parameters in order to render
|
45
45
|
# dynamic content. This can be in the form of regular or named parameters. The
|
46
46
|
# `greeter` template shown above takes a single `name` parameter. Here's how a
|
47
|
-
# anchor
|
47
|
+
# anchor template could be implemented with named parameters:
|
48
48
|
#
|
49
49
|
# anchor = Papercraft.html { |uri: , text: | a(text, href: uri) }
|
50
50
|
#
|
51
|
-
# The above
|
51
|
+
# The above template could later be rendered by passing the needed arguments:
|
52
52
|
#
|
53
53
|
# anchor.render(uri: 'https://example.com', text: 'Example')
|
54
54
|
#
|
55
|
-
# ##
|
55
|
+
# ## Template Composition
|
56
56
|
#
|
57
|
-
# A
|
57
|
+
# A template can be included in another template using the `emit` method:
|
58
58
|
#
|
59
59
|
# links = Papercraft.html {
|
60
60
|
# emit anchor, uri: '/posts', text: 'Posts'
|
@@ -62,7 +62,7 @@ module Papercraft
|
|
62
62
|
# emit anchor, uri: '/about', text: 'About'
|
63
63
|
# }
|
64
64
|
#
|
65
|
-
# Another way of composing
|
65
|
+
# Another way of composing templates is to pass the templates themselves as
|
66
66
|
# parameters:
|
67
67
|
#
|
68
68
|
# links = Papercraft.html { |anchors|
|
@@ -74,8 +74,8 @@ module Papercraft
|
|
74
74
|
# anchor.apply(uri: '/about', text: 'About')
|
75
75
|
# ])
|
76
76
|
#
|
77
|
-
# The `#apply` method creates a new
|
78
|
-
# such that the
|
77
|
+
# The `#apply` method creates a new template, applying the given parameters
|
78
|
+
# such that the template can be rendered without parameters:
|
79
79
|
#
|
80
80
|
# links_with_anchors = links.apply([
|
81
81
|
# anchor.apply(uri: '/posts', text: 'Posts'),
|
@@ -84,7 +84,7 @@ module Papercraft
|
|
84
84
|
# ])
|
85
85
|
# links_with_anchors.render
|
86
86
|
#
|
87
|
-
class
|
87
|
+
class Template < Proc
|
88
88
|
|
89
89
|
# Determines the rendering mode: `:html` or `:xml`.
|
90
90
|
attr_accessor :mode
|
@@ -95,12 +95,12 @@ module Papercraft
|
|
95
95
|
json: 'application/json'
|
96
96
|
}.freeze
|
97
97
|
|
98
|
-
# Initializes a
|
98
|
+
# Initializes a template with the given block. The rendering mode (HTML or
|
99
99
|
# XML) can be passed in the `mode:` parameter. If `mode:` is not specified,
|
100
|
-
# the
|
100
|
+
# the template defaults to HTML.
|
101
101
|
#
|
102
102
|
# @param mode [:html, :xml] rendering mode
|
103
|
-
# @param mime_type [String, nil] the
|
103
|
+
# @param mime_type [String, nil] the template's mime type (nil for default)
|
104
104
|
# @param block [Proc] nested HTML block
|
105
105
|
def initialize(mode: :html, mime_type: nil, &block)
|
106
106
|
@mode = mode
|
@@ -124,9 +124,9 @@ module Papercraft
|
|
124
124
|
end.to_s
|
125
125
|
end
|
126
126
|
|
127
|
-
# Creates a new
|
127
|
+
# Creates a new template, applying the given parameters and or block to the
|
128
128
|
# current one. Application is one of the principal methods of composing
|
129
|
-
#
|
129
|
+
# templates, particularly when passing inner templates as blocks:
|
130
130
|
#
|
131
131
|
# article_wrapper = Papercraft.html {
|
132
132
|
# article {
|
@@ -141,19 +141,19 @@ module Papercraft
|
|
141
141
|
# @param *a [<any>] normal parameters
|
142
142
|
# @param **b [Hash] named parameters
|
143
143
|
# @param &block [Proc] inner block
|
144
|
-
# @return [Papercraft::
|
144
|
+
# @return [Papercraft::Template] applied template
|
145
145
|
def apply(*a, **b, &block)
|
146
146
|
template = self
|
147
|
-
|
147
|
+
Template.new(mode: @mode, mime_type: @mime_type, &proc do |*x, **y|
|
148
148
|
push_emit_yield_block(block) if block
|
149
149
|
instance_exec(*a, *x, **b, **y, &template)
|
150
150
|
end)
|
151
151
|
end
|
152
152
|
|
153
153
|
# Returns the Renderer class used for rendering the templates, according to
|
154
|
-
# the
|
154
|
+
# the template's mode.
|
155
155
|
#
|
156
|
-
# @return [Papercraft::Renderer] Renderer used for rendering the
|
156
|
+
# @return [Papercraft::Renderer] Renderer used for rendering the template
|
157
157
|
def renderer_class
|
158
158
|
case @mode
|
159
159
|
when :html
|
data/lib/papercraft/version.rb
CHANGED
data/lib/papercraft.rb
CHANGED
@@ -4,13 +4,13 @@ require 'kramdown'
|
|
4
4
|
require 'rouge'
|
5
5
|
require 'kramdown-parser-gfm'
|
6
6
|
|
7
|
-
require_relative 'papercraft/
|
7
|
+
require_relative 'papercraft/template'
|
8
8
|
require_relative 'papercraft/renderer'
|
9
9
|
require_relative 'papercraft/encoding'
|
10
10
|
# require_relative 'papercraft/compiler'
|
11
11
|
|
12
12
|
|
13
|
-
# Papercraft is a
|
13
|
+
# Papercraft is a composable templating library
|
14
14
|
module Papercraft
|
15
15
|
# Exception class used to signal templating-related errors
|
16
16
|
class Error < RuntimeError; end
|
@@ -31,49 +31,49 @@ module Papercraft
|
|
31
31
|
Renderer.extension(map)
|
32
32
|
end
|
33
33
|
|
34
|
-
# Creates a new papercraft
|
34
|
+
# Creates a new papercraft template. `Papercraft.html` can take either a proc
|
35
35
|
# argument or a block. In both cases, the proc is converted to a
|
36
|
-
# `Papercraft::
|
36
|
+
# `Papercraft::Template`.
|
37
37
|
#
|
38
38
|
# Papercraft.html(proc { h1 'hi' }).render #=> "<h1>hi</h1>"
|
39
39
|
# Papercraft.html { h1 'hi' }.render #=> "<h1>hi</h1>"
|
40
40
|
#
|
41
41
|
# @param template [Proc] template block
|
42
|
-
# @return [Papercraft::
|
42
|
+
# @return [Papercraft::Template] Papercraft template
|
43
43
|
def html(o = nil, mime_type: nil, &template)
|
44
|
-
return o if o.is_a?(Papercraft::
|
44
|
+
return o if o.is_a?(Papercraft::Template)
|
45
45
|
template ||= o
|
46
|
-
Papercraft::
|
46
|
+
Papercraft::Template.new(mode: :html, mime_type: mime_type, &template)
|
47
47
|
end
|
48
48
|
|
49
|
-
# Creates a new
|
49
|
+
# Creates a new Papercraft template in XML mode. `Papercraft.xml` can take
|
50
50
|
# either a proc argument or a block. In both cases, the proc is converted to a
|
51
|
-
# `Papercraft::
|
51
|
+
# `Papercraft::Template`.
|
52
52
|
#
|
53
53
|
# Papercraft.xml(proc { item 'foo' }).render #=> "<item>foo</item>"
|
54
54
|
# Papercraft.xml { item 'foo' }.render #=> "<item>foo</item>"
|
55
55
|
#
|
56
56
|
# @param template [Proc] template block
|
57
|
-
# @return [Papercraft::
|
57
|
+
# @return [Papercraft::Template] Papercraft template
|
58
58
|
def xml(o = nil, mime_type: nil, &template)
|
59
|
-
return o if o.is_a?(Papercraft::
|
59
|
+
return o if o.is_a?(Papercraft::Template)
|
60
60
|
template ||= o
|
61
|
-
Papercraft::
|
61
|
+
Papercraft::Template.new(mode: :xml, mime_type: mime_type, &template)
|
62
62
|
end
|
63
63
|
|
64
|
-
# Creates a new
|
64
|
+
# Creates a new Papercraft template in JSON mode. `Papercraft.json` can take
|
65
65
|
# either a proc argument or a block. In both cases, the proc is converted to a
|
66
|
-
# `Papercraft::
|
66
|
+
# `Papercraft::Template`.
|
67
67
|
#
|
68
68
|
# Papercraft.json(proc { item 42 }).render #=> "[42]"
|
69
69
|
# Papercraft.json { foo 'bar' }.render #=> "{\"foo\": \"bar\"}"
|
70
70
|
#
|
71
71
|
# @param template [Proc] template block
|
72
|
-
# @return [Papercraft::
|
72
|
+
# @return [Papercraft::Template] Papercraft template
|
73
73
|
def json(o = nil, mime_type: nil, &template)
|
74
|
-
return o if o.is_a?(Papercraft::
|
74
|
+
return o if o.is_a?(Papercraft::Template)
|
75
75
|
template ||= o
|
76
|
-
Papercraft::
|
76
|
+
Papercraft::Template.new(mode: :json, mime_type: mime_type, &template)
|
77
77
|
end
|
78
78
|
|
79
79
|
# Renders Markdown into HTML. The `opts` argument will be merged with the
|
data/papercraft.png
ADDED
Binary file
|
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.19'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-02-
|
11
|
+
date: 2022-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: escape_utils
|
@@ -128,18 +128,20 @@ executables: []
|
|
128
128
|
extensions: []
|
129
129
|
extra_rdoc_files:
|
130
130
|
- README.md
|
131
|
+
- papercraft.png
|
131
132
|
files:
|
132
133
|
- CHANGELOG.md
|
133
134
|
- README.md
|
134
135
|
- lib/papercraft.rb
|
135
136
|
- lib/papercraft/compiler.rb
|
136
|
-
- lib/papercraft/component.rb
|
137
137
|
- lib/papercraft/encoding.rb
|
138
138
|
- lib/papercraft/extension_proxy.rb
|
139
139
|
- lib/papercraft/html.rb
|
140
140
|
- lib/papercraft/json.rb
|
141
141
|
- lib/papercraft/renderer.rb
|
142
|
+
- lib/papercraft/template.rb
|
142
143
|
- lib/papercraft/version.rb
|
144
|
+
- papercraft.png
|
143
145
|
homepage: http://github.com/digital-fabric/papercraft
|
144
146
|
licenses:
|
145
147
|
- MIT
|