papercraft 0.23 → 0.24
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 +5 -0
- data/README.md +64 -43
- data/lib/papercraft/renderer.rb +9 -9
- data/lib/papercraft/tags.rb +35 -9
- data/lib/papercraft/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f90c4ea6ac9d3090ae45d79f7f4a58668ccf7f8ae5d4dfa2a727b44a82699eb9
|
4
|
+
data.tar.gz: 10ff5bc3df10c10b0a968921517d2e0c18a61973dd97b88e95eef38670b9e451
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '02461962ba174678a5b4a6ec550a8faa2f643fe87234e41513f7b49d798e3f3b2ade02adcfb0fa4961124a74484ddddea9437cb02eec98e9e897721729c0ef63'
|
7
|
+
data.tar.gz: f99728bb218382a040f67cbf2fd9652c33b3e0648efefbc695ceee708006758b6ec249748f3e3d41b065bf3b2fb28014b1ae61e02f7d3b01231e928f028e6ebd
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -42,6 +42,10 @@ Papercraft includes built-in support for rendering Markdown (using
|
|
42
42
|
creating template extensions in order to allow the creation of component
|
43
43
|
libraries.
|
44
44
|
|
45
|
+
Papercraft automatically escapes all text emitted in templates according to the
|
46
|
+
template type. For more information see the section on [escaping
|
47
|
+
content](#escaping-content).
|
48
|
+
|
45
49
|
```ruby
|
46
50
|
require 'papercraft'
|
47
51
|
|
@@ -59,29 +63,30 @@ hello.render('world')
|
|
59
63
|
#=> "<html><head><title>Title</title></head><body><h1>Hello, world!</h1></body></html>"
|
60
64
|
```
|
61
65
|
|
62
|
-
## Table of
|
63
|
-
|
64
|
-
- [Installing
|
65
|
-
- [Basic
|
66
|
-
- [Adding
|
67
|
-
- [Tag and
|
68
|
-
- [
|
69
|
-
- [Template
|
70
|
-
- [Template
|
71
|
-
- [
|
72
|
-
- [
|
73
|
-
- [
|
74
|
-
- [
|
75
|
-
- [
|
76
|
-
- [
|
77
|
-
- [Emitting
|
66
|
+
## Table of Content
|
67
|
+
|
68
|
+
- [Installing Papercraft](#installing-papercraft)
|
69
|
+
- [Basic Usage](#basic-usage)
|
70
|
+
- [Adding Tags](#adding-tags)
|
71
|
+
- [Tag and Attribute Formatting](#tag-and-attribute-formatting)
|
72
|
+
- [Escaping Content](#escaping-content)
|
73
|
+
- [Template Parameters](#template-parameters)
|
74
|
+
- [Template Logic](#template-logic)
|
75
|
+
- [Template Blocks](#template-blocks)
|
76
|
+
- [Plain Procs as Templates](#plain-procs-as-templates)
|
77
|
+
- [Template Composition](#template-composition)
|
78
|
+
- [Parameter and Block Application](#parameter-and-block-application)
|
79
|
+
- [Higher-Order Templates](#higher-order-templates)
|
80
|
+
- [Layout Template Composition](#layout-template-composition)
|
81
|
+
- [Emitting Raw HTML](#emitting-raw-html)
|
82
|
+
- [Emitting a String with HTML Encoding](#emitting-a-string-with-html-encoding)
|
78
83
|
- [Emitting Markdown](#emitting-markdown)
|
79
|
-
- [Working with MIME
|
80
|
-
- [Deferred
|
81
|
-
- [XML
|
82
|
-
- [JSON
|
83
|
-
- [Papercraft
|
84
|
-
- [Bundled
|
84
|
+
- [Working with MIME Types](#working-with-mime-types)
|
85
|
+
- [Deferred Evaluation](#deferred-evaluation)
|
86
|
+
- [XML Templates](#xml-templates)
|
87
|
+
- [JSON Templates](#json-templates)
|
88
|
+
- [Papercraft Extensions](#papercraft-extensions)
|
89
|
+
- [Bundled Extensions](#bundled-extensions)
|
85
90
|
- [API Reference](#api-reference)
|
86
91
|
|
87
92
|
## Installing Papercraft
|
@@ -98,7 +103,7 @@ Or manually:
|
|
98
103
|
$ gem install papercraft
|
99
104
|
```
|
100
105
|
|
101
|
-
## Basic
|
106
|
+
## Basic Usage
|
102
107
|
|
103
108
|
To create an HTML template use `Papercraft.html`:
|
104
109
|
|
@@ -119,7 +124,7 @@ Rendering a template is done using `#render`:
|
|
119
124
|
html.render #=> "<div id="greeter"><p>Hello!</p></div>"
|
120
125
|
```
|
121
126
|
|
122
|
-
## Adding
|
127
|
+
## Adding Tags
|
123
128
|
|
124
129
|
Tags are added using unqualified method calls, and can be nested using blocks:
|
125
130
|
|
@@ -156,7 +161,7 @@ Papercraft.html { img src: '/my.gif' }.render #=> "<img src="/my.gif"/>
|
|
156
161
|
Papercraft.html { p "foobar", class: 'important' }.render #=> "<p class=\"important\">foobar</p>"
|
157
162
|
```
|
158
163
|
|
159
|
-
## Tag and
|
164
|
+
## Tag and Attribute Formatting
|
160
165
|
|
161
166
|
Papercraft does not make any presumption about what tags and attributes you can
|
162
167
|
use. You can mix upper and lower case letters, and you can include arbitrary
|
@@ -193,7 +198,23 @@ Papercraft.html {
|
|
193
198
|
}.render #=> '<cra_zy__:!tag>foo</cra_zy__:!tag>'
|
194
199
|
```
|
195
200
|
|
196
|
-
##
|
201
|
+
## Escaping Content
|
202
|
+
|
203
|
+
Papercraft automatically escapes all text content emitted in a template. The
|
204
|
+
specific escaping algorithm depends on the template type. For both HTML and XML
|
205
|
+
templates, Papercraft uses
|
206
|
+
[escape_utils](https://github.com/brianmario/escape_utils), specifically:
|
207
|
+
|
208
|
+
- HTML: `escape_utils.escape_html`
|
209
|
+
- XML: `escape_utils.escape_xml`
|
210
|
+
|
211
|
+
In order to emit raw HTML/XML, you can use the `#emit` method as [described
|
212
|
+
below](#emitting-raw-html).
|
213
|
+
|
214
|
+
JSON templates are rendered using the `json` gem bundled with Ruby, which takes
|
215
|
+
care of escaping text values.
|
216
|
+
|
217
|
+
## Template Parameters
|
197
218
|
|
198
219
|
In Papercraft, parameters are always passed explicitly. This means that template
|
199
220
|
parameters are specified as block parameters, and are passed to the template on
|
@@ -211,7 +232,7 @@ greeting = Papercraft.html { |name:| h1 "Hello, #{name}!" }
|
|
211
232
|
greeting.render(name: 'world') #=> "<h1>Hello, world!</h1>"
|
212
233
|
```
|
213
234
|
|
214
|
-
## Template
|
235
|
+
## Template Logic
|
215
236
|
|
216
237
|
Since Papercraft templates are just a bunch of Ruby, you can easily write your
|
217
238
|
view logic right in the template:
|
@@ -226,7 +247,7 @@ Papercraft.html { |user = nil|
|
|
226
247
|
}
|
227
248
|
```
|
228
249
|
|
229
|
-
## Template
|
250
|
+
## Template Blocks
|
230
251
|
|
231
252
|
Templates can also accept and render blocks by using `emit_yield`:
|
232
253
|
|
@@ -241,7 +262,7 @@ page = Papercraft.html {
|
|
241
262
|
page.render { h1 'hi' }
|
242
263
|
```
|
243
264
|
|
244
|
-
## Plain
|
265
|
+
## Plain Procs as Templates
|
245
266
|
|
246
267
|
With Papercraft you can write a template as a plain Ruby proc, and later render
|
247
268
|
it by passing it as a block to `Papercraft.html`:
|
@@ -258,7 +279,7 @@ greeting = ->(name) { h1 "Hello, #{name}!" }
|
|
258
279
|
Papercraft.html(&greeting).render('world')
|
259
280
|
```
|
260
281
|
|
261
|
-
## Template
|
282
|
+
## Template Composition
|
262
283
|
|
263
284
|
Papercraft makes it easy to compose multiple templates into a whole HTML
|
264
285
|
document. A Papercraft template can contain other templates, as the following
|
@@ -308,7 +329,7 @@ Papercraft.html {
|
|
308
329
|
}
|
309
330
|
```
|
310
331
|
|
311
|
-
## Parameter and
|
332
|
+
## Parameter and Block Application
|
312
333
|
|
313
334
|
Parameters and blocks can be applied to a template without it being rendered, by
|
314
335
|
using `#apply`. This mechanism is what allows template composition and the
|
@@ -333,7 +354,7 @@ wrapped_hello_world = div_wrap.apply(&hello_world)
|
|
333
354
|
wrapped_hello_world.render #=> "<div><h1>Hello, world!</h1></div>"
|
334
355
|
```
|
335
356
|
|
336
|
-
## Higher-
|
357
|
+
## Higher-Order Templates
|
337
358
|
|
338
359
|
Papercraft also lets you create higher-order templates, that is,
|
339
360
|
templates that take other templates as parameters, or as blocks. Higher-order
|
@@ -357,7 +378,7 @@ wrapped_greeter = div_wrap.apply { h1 'hi' }
|
|
357
378
|
wrapped_greeter.render #=> "<div><h1>hi</h1></div>"
|
358
379
|
```
|
359
380
|
|
360
|
-
## Layout
|
381
|
+
## Layout Template Composition
|
361
382
|
|
362
383
|
One of the principal uses of higher-order templates is the creation of nested
|
363
384
|
layouts. Suppose we have a website with a number of different layouts, and we'd
|
@@ -390,7 +411,7 @@ article_layout.render(
|
|
390
411
|
)
|
391
412
|
```
|
392
413
|
|
393
|
-
## Emitting
|
414
|
+
## Emitting Raw HTML
|
394
415
|
|
395
416
|
Raw HTML can be emitted using `#emit`:
|
396
417
|
|
@@ -399,13 +420,13 @@ wrapped = Papercraft.html { |html| div { emit html } }
|
|
399
420
|
wrapped.render("<h1>hi</h1>") #=> "<div><h1>hi</h1></div>"
|
400
421
|
```
|
401
422
|
|
402
|
-
## Emitting a
|
423
|
+
## Emitting a String with HTML Encoding
|
403
424
|
|
404
425
|
To emit a string with proper HTML encoding, without wrapping it in an HTML
|
405
426
|
element, use `#text`:
|
406
427
|
|
407
428
|
```ruby
|
408
|
-
Papercraft.html {
|
429
|
+
Papercraft.html { text 'hi&lo' }.render #=> "hi&lo"
|
409
430
|
```
|
410
431
|
|
411
432
|
## Emitting Markdown
|
@@ -454,7 +475,7 @@ The deafult options can be configured by accessing
|
|
454
475
|
Papercraft.default_kramdown_options[:auto_ids] = false
|
455
476
|
```
|
456
477
|
|
457
|
-
## Working with MIME
|
478
|
+
## Working with MIME Types
|
458
479
|
|
459
480
|
Papercraft lets you set and interrogate a template's MIME type, in order to be
|
460
481
|
able to dynamically set the `Content-Type` HTTP response header. A template's
|
@@ -470,7 +491,7 @@ def serve_template(req, template)
|
|
470
491
|
end
|
471
492
|
```
|
472
493
|
|
473
|
-
## Deferred
|
494
|
+
## Deferred Evaluation
|
474
495
|
|
475
496
|
Deferred evaluation allows deferring the rendering of parts of a template until
|
476
497
|
the last moment, thus allowing an inner template to manipulate the state of the
|
@@ -522,7 +543,7 @@ page = default_layout.apply {
|
|
522
543
|
}
|
523
544
|
```
|
524
545
|
|
525
|
-
## XML
|
546
|
+
## XML Templates
|
526
547
|
|
527
548
|
XML templates behave largely the same as HTML templates, with a few minor
|
528
549
|
differences. XML templates employ a different encoding algorithm, and lack some
|
@@ -557,7 +578,7 @@ rss = Papercraft.xml(mime_type: 'text/xml; charset=utf-8') { |resource:, **props
|
|
557
578
|
}
|
558
579
|
```
|
559
580
|
|
560
|
-
## JSON
|
581
|
+
## JSON Templates
|
561
582
|
|
562
583
|
JSON templates behave largely the same as HTML and XML templates. The only major
|
563
584
|
difference is that for adding array items you'll need to use the `#item` method:
|
@@ -588,7 +609,7 @@ Papercraft.json {
|
|
588
609
|
Papercraft uses the [JSON gem](https://rubyapi.org/3.1/o/json) under the hood in
|
589
610
|
order to generate actual JSON.
|
590
611
|
|
591
|
-
## Papercraft
|
612
|
+
## Papercraft Extensions
|
592
613
|
|
593
614
|
Papercraft extensions are modules that contain one or more methods that can be
|
594
615
|
used to render complex HTML components. Extension modules can be used by
|
@@ -669,7 +690,7 @@ be specifically required in order to be available to templates.
|
|
669
690
|
For all bundled Papercraft extensions, there's no need to call
|
670
691
|
`Papercraft.extension`, requiring the extension is sufficient.
|
671
692
|
|
672
|
-
### SOAP
|
693
|
+
### SOAP Extension
|
673
694
|
|
674
695
|
> The SOAP extension was contributed by [@aemadrid](https://github.com/aemadrid).
|
675
696
|
|
@@ -713,4 +734,4 @@ xml = Papercraft.xml {
|
|
713
734
|
## API Reference
|
714
735
|
|
715
736
|
The API reference for this library can be found
|
716
|
-
[here](https://www.rubydoc.info/gems/papercraft).
|
737
|
+
[here](https://www.rubydoc.info/gems/papercraft).
|
data/lib/papercraft/renderer.rb
CHANGED
@@ -47,17 +47,17 @@ module Papercraft
|
|
47
47
|
# components. In cases where method names in the module clash with XML
|
48
48
|
# tag names, you can use the `#tag` method to emit the relevant tag.
|
49
49
|
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
50
|
+
# module ComponentLibrary
|
51
|
+
# def card(title, content)
|
52
|
+
# div(class: 'card') {
|
53
|
+
# h3 title
|
54
|
+
# div(class: 'card-content') { emit_markdown content }
|
55
|
+
# }
|
56
|
+
# end
|
56
57
|
# end
|
57
|
-
# end
|
58
58
|
#
|
59
|
-
#
|
60
|
-
#
|
59
|
+
# Papercraft.extension(components: ComponentLibrary)
|
60
|
+
# Papercraft.html { components.card('Foo', '**Bar**') }
|
61
61
|
#
|
62
62
|
# @param map [Hash] hash mapping methods to extension modules
|
63
63
|
# @return [void]
|
data/lib/papercraft/tags.rb
CHANGED
@@ -161,14 +161,13 @@ module Papercraft
|
|
161
161
|
# @return [void]
|
162
162
|
def method_missing(sym, *args, **opts, &block)
|
163
163
|
tag = sym.to_s
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
self.class.class_eval(code, __FILE__, S_TAG_METHOD_LINE)
|
164
|
+
if tag =~ /^[A-Z]/ && (Object.const_defined?(tag))
|
165
|
+
define_const_tag_method(tag)
|
166
|
+
# return send(tag, *args, **opts)
|
167
|
+
else
|
168
|
+
define_tag_method(tag)
|
169
|
+
end
|
170
|
+
|
172
171
|
send(sym, *args, **opts, &block)
|
173
172
|
end
|
174
173
|
|
@@ -183,6 +182,33 @@ module Papercraft
|
|
183
182
|
|
184
183
|
private
|
185
184
|
|
185
|
+
# Defines a method that emits the given tag based on a constant. The
|
186
|
+
# constant must be defined on the main (Object) binding.
|
187
|
+
#
|
188
|
+
# @param tag [Symbol, String] tag/method name
|
189
|
+
# @return [void]
|
190
|
+
def define_const_tag_method(tag)
|
191
|
+
const = Object.const_get(tag)
|
192
|
+
self.class.define_method(tag) { |*a, **b, &blk|
|
193
|
+
emit const, *a, **b, &blk
|
194
|
+
}
|
195
|
+
end
|
196
|
+
|
197
|
+
# Defines a normal tag method.
|
198
|
+
#
|
199
|
+
# @param tag [Symbol, String] tag/method name
|
200
|
+
# @return [void]
|
201
|
+
def define_tag_method(tag)
|
202
|
+
repr = tag_repr(tag)
|
203
|
+
code = S_TAG_METHOD % {
|
204
|
+
tag: tag,
|
205
|
+
TAG: tag.upcase,
|
206
|
+
tag_pre: "<#{repr}".inspect,
|
207
|
+
tag_close: "</#{repr}>".inspect
|
208
|
+
}
|
209
|
+
self.class.class_eval(code, __FILE__, S_TAG_METHOD_LINE)
|
210
|
+
end
|
211
|
+
|
186
212
|
# Emits an arbitrary object by converting it to string, then adding it to
|
187
213
|
# the internal buffer. This method is called internally by `Renderer#emit`.
|
188
214
|
#
|
@@ -251,7 +277,7 @@ module Papercraft
|
|
251
277
|
# emit nothing
|
252
278
|
else
|
253
279
|
@buffer << S_SPACE << att_repr(k) <<
|
254
|
-
S_EQUAL_QUOTE << v << S_QUOTE
|
280
|
+
S_EQUAL_QUOTE << escape_text(v) << S_QUOTE
|
255
281
|
end
|
256
282
|
end
|
257
283
|
}
|
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.24'
|
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-
|
11
|
+
date: 2022-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: escape_utils
|