papercraft 0.23 → 0.24

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 341520b9db20c53da441299fb449c4eea3321924517f4b93e70af1119b4516c3
4
- data.tar.gz: 861a5a2747c3a468abb780cf50710698e52fbac1fc236c8672c2bbb328db6f4d
3
+ metadata.gz: f90c4ea6ac9d3090ae45d79f7f4a58668ccf7f8ae5d4dfa2a727b44a82699eb9
4
+ data.tar.gz: 10ff5bc3df10c10b0a968921517d2e0c18a61973dd97b88e95eef38670b9e451
5
5
  SHA512:
6
- metadata.gz: 7668a984a2c7957ba3f65234eab6770b4e969e0d2b4e1345839db8c0711d07afbfef5735b67de9a94c22994b4b6c1d6b2f87e07a810a0cae04ccbecb1ff5b38f
7
- data.tar.gz: 1605f9b1459ab20b9cec97805529764ece6058ce34609dc7d75fe38d8b35889c65e4afa5174f1c1d89dfb46205d282e65e1020995c999f66b84a5f9b5e505de1
6
+ metadata.gz: '02461962ba174678a5b4a6ec550a8faa2f643fe87234e41513f7b49d798e3f3b2ade02adcfb0fa4961124a74484ddddea9437cb02eec98e9e897721729c0ef63'
7
+ data.tar.gz: f99728bb218382a040f67cbf2fd9652c33b3e0648efefbc695ceee708006758b6ec249748f3e3d41b065bf3b2fb28014b1ae61e02f7d3b01231e928f028e6ebd
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.24 2022-03-19
2
+
3
+ - Fix usage of const components (#13)
4
+ - Fix formatting of HTML/XML attributes for non-string values
5
+
1
6
  ## 0.23 2022-02-15
2
7
 
3
8
  - Remove unused `Encoding` module
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 content
63
-
64
- - [Installing papercraft](#installing-papercraft)
65
- - [Basic usage](#basic-usage)
66
- - [Adding tags](#adding-tags)
67
- - [Tag and attribute formatting](#tag-and-attribute-formatting)
68
- - [Template parameters](#template-parameters)
69
- - [Template logic](#template-logic)
70
- - [Template blocks](#template-blocks)
71
- - [Plain procs as templates](#plain-procs-as-templates)
72
- - [Template composition](#template-composition)
73
- - [Parameter and block application](#parameter-and-block-application)
74
- - [Higher-order templates](#higher-order-templates)
75
- - [Layout template composition](#layout-template-composition)
76
- - [Emitting raw HTML](#emitting-raw-html)
77
- - [Emitting a string with HTML Encoding](#emitting-a-string-with-html-encoding)
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 types](#working-with-mime-types)
80
- - [Deferred evaluation](#deferred-evaluation)
81
- - [XML templates](#xml-templates)
82
- - [JSON templates](#json-templates)
83
- - [Papercraft extensions](#papercraft-extensions)
84
- - [Bundled extensions](#bundled-extensions)
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 usage
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 tags
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 attribute formatting
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
- ## Template parameters
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 logic
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 blocks
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 procs as templates
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 composition
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 block application
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-order templates
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 template composition
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 raw HTML
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 string with HTML Encoding
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 { str 'hi&lo' }.render #=> "hi&amp;lo"
429
+ Papercraft.html { text 'hi&lo' }.render #=> "hi&amp;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 types
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 evaluation
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 templates
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 templates
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 extensions
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 extension
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).
@@ -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
- # module ComponentLibrary
51
- # def card(title, content)
52
- # div(class: 'card') {
53
- # h3 title
54
- # div(class: 'card-content') { emit_markdown content }
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
- # Papercraft.extension(components: ComponentLibrary)
60
- # Papercraft.html { components.card('Foo', '**Bar**') }
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]
@@ -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
- repr = tag_repr(tag)
165
- code = S_TAG_METHOD % {
166
- tag: tag,
167
- TAG: tag.upcase,
168
- tag_pre: "<#{repr}".inspect,
169
- tag_close: "</#{repr}>".inspect
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
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Papercraft
4
- VERSION = '0.23'
4
+ VERSION = '0.24'
5
5
  end
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.23'
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-02-15 00:00:00.000000000 Z
11
+ date: 2022-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: escape_utils