papercraft 0.23 → 0.24
Sign up to get free protection for your applications and to get access to all the features.
- 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
|