props_template 0.17.1 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +193 -98
- data/lib/props_template.rb +1 -0
- data/lib/props_template/version.rb +3 -0
- metadata +11 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4cf7de015844e77efdf93e02272159080835cad2e0f6022e610690727a05cfb5
|
4
|
+
data.tar.gz: 350d1a534d30c625b7adbe3c95d6ac33c2a831205c970c404bb2c9eeb22dfd69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 533ff82a0dac43e211d9a5800b71ef9ec59a4e8d34d16214a3799ea7398e9746a1d0b823db55bfd4b272ea9a48a9e685a3f49fc437f8b7a7aa1ed49ef2d531c8
|
7
|
+
data.tar.gz: 0fc9fc3e0b1d898c1870c286d14dcd59e8a6679d428c026dcf2c6107ef8e281f40d0e08838f625e1a39b321199510920fe2e3a1b9ff20a08990106220fffc949
|
data/README.md
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
# PropsTemplate
|
2
2
|
|
3
|
-
PropsTemplate is a direct-to-Oj, JBuilder-like DSL for building JSON. It has
|
3
|
+
PropsTemplate is a direct-to-Oj, JBuilder-like DSL for building JSON. It has
|
4
|
+
support for Russian-Doll caching, layouts, and can be queried by giving the
|
5
|
+
root a key path.
|
4
6
|
|
5
|
-
|
7
|
+
[![Build
|
8
|
+
Status](https://circleci.com/gh/thoughtbot/props_template.svg?style=shield)](https://circleci.com/gh/thoughtbot/props_template)
|
6
9
|
|
7
|
-
|
10
|
+
It's fast.
|
8
11
|
|
9
|
-
PropsTemplate
|
12
|
+
PropsTemplate bypasses the steps of hash building and serializing
|
13
|
+
that other libraries perform by using Oj's `StringWriter` in `rails` mode.
|
10
14
|
|
15
|
+
![benchmarks](docs/benchmarks.png)
|
11
16
|
|
12
|
-
|
17
|
+
Caching is fast too.
|
18
|
+
|
19
|
+
While other libraries spend time unmarshaling,
|
20
|
+
merging hashes, and serializing to JSON; PropsTemplate simply takes
|
21
|
+
the cached string and uses Oj's [push_json](http://www.ohler.com/oj/doc/Oj/StringWriter.html#push_json-instance_method).
|
22
|
+
|
23
|
+
## Example:
|
24
|
+
|
25
|
+
PropsTemplate is very similar to JBuilder, and selectively retains some
|
26
|
+
conveniences and magic.
|
13
27
|
|
14
28
|
```ruby
|
15
29
|
json.flash flash.to_h
|
@@ -47,13 +61,11 @@ json.posts do
|
|
47
61
|
json.total @posts.count
|
48
62
|
end
|
49
63
|
|
50
|
-
|
51
64
|
json.footer partial: 'shared/footer' do
|
52
65
|
end
|
53
66
|
```
|
54
67
|
|
55
68
|
## Installation
|
56
|
-
If you plan to use PropsTemplate alone just add it to your Gemfile.
|
57
69
|
|
58
70
|
```
|
59
71
|
gem 'props_template'
|
@@ -63,18 +75,19 @@ and run `bundle`
|
|
63
75
|
|
64
76
|
## API
|
65
77
|
|
66
|
-
### json.set! or json
|
67
|
-
|
78
|
+
### json.set! or json.\<your key here\>
|
79
|
+
|
80
|
+
Defines the attribute or structure. All keys are automatically camelized lower.
|
68
81
|
|
69
82
|
```ruby
|
70
|
-
json.set! :author_details, {
|
83
|
+
json.set! :author_details, {...options} do
|
71
84
|
json.set! :first_name, 'David'
|
72
85
|
end
|
73
86
|
|
74
87
|
or
|
75
88
|
|
76
|
-
json.author_details, {
|
77
|
-
json.first_name
|
89
|
+
json.author_details, {...options} do
|
90
|
+
json.first_name 'David'
|
78
91
|
end
|
79
92
|
|
80
93
|
|
@@ -89,6 +102,7 @@ The inline form defines key and value
|
|
89
102
|
| value | A value |
|
90
103
|
|
91
104
|
```ruby
|
105
|
+
|
92
106
|
json.set! :first_name, 'David'
|
93
107
|
|
94
108
|
or
|
@@ -108,39 +122,36 @@ The block form defines key and structure
|
|
108
122
|
|
109
123
|
```ruby
|
110
124
|
json.set! :details do
|
111
|
-
|
125
|
+
...
|
112
126
|
end
|
113
127
|
|
114
128
|
or
|
115
129
|
|
116
130
|
json.details do
|
117
|
-
|
131
|
+
...
|
118
132
|
end
|
119
133
|
```
|
120
134
|
|
121
135
|
The difference between the block form and inline form is
|
122
|
-
1. The block form is an internal node.
|
123
|
-
|
136
|
+
1. The block form is an internal node. Functionality such as Partials,
|
137
|
+
Deferment and other [options](#options) are only available on the
|
138
|
+
block form.
|
139
|
+
2. The inline form is considered a leaf node, and you can only [search](#traversing)
|
140
|
+
for internal nodes.
|
124
141
|
|
125
142
|
### json.array!
|
126
143
|
Generates an array of json objects.
|
127
144
|
|
128
145
|
```ruby
|
129
|
-
collection = [
|
130
|
-
{name: 'john'},
|
131
|
-
{name: 'jim'}
|
132
|
-
]
|
146
|
+
collection = [ {name: 'john'}, {name: 'jim'} ]
|
133
147
|
|
134
148
|
json.details do
|
135
|
-
json.array! collection, {
|
149
|
+
json.array! collection, {...options} do |person|
|
136
150
|
json.first_name person[:name]
|
137
151
|
end
|
138
152
|
end
|
139
153
|
|
140
|
-
# => {"details": [
|
141
|
-
{"firstName": 'john'},
|
142
|
-
{"firstName": 'jim'}
|
143
|
-
]}
|
154
|
+
# => {"details": [{"firstName": 'john'}, {"firstName": 'jim'} ]}
|
144
155
|
```
|
145
156
|
|
146
157
|
| Parameter | Notes |
|
@@ -148,7 +159,8 @@ end
|
|
148
159
|
| collection | A collection that responds to `member_at` and `member_by` |
|
149
160
|
| options | Additional [options](#options)|
|
150
161
|
|
151
|
-
To support [traversing nodes](
|
162
|
+
To support [traversing nodes](#traversing), any list passed
|
163
|
+
to `array!` MUST implement `member_at(index)` and `member_by(attr, value)`.
|
152
164
|
|
153
165
|
For example, if you were using a delegate:
|
154
166
|
|
@@ -169,7 +181,10 @@ end
|
|
169
181
|
Then in your template:
|
170
182
|
|
171
183
|
```ruby
|
172
|
-
data = ObjectCollection.new([
|
184
|
+
data = ObjectCollection.new([
|
185
|
+
{id: 1, name: 'foo'},
|
186
|
+
{id: 2, name: 'bar'}
|
187
|
+
])
|
173
188
|
|
174
189
|
json.array! data do
|
175
190
|
...
|
@@ -200,11 +215,15 @@ end
|
|
200
215
|
|
201
216
|
#### **Array core extension**
|
202
217
|
|
203
|
-
For convenience, PropsTemplate includes a core\_ext that adds these methods to
|
218
|
+
For convenience, PropsTemplate includes a core\_ext that adds these methods to
|
219
|
+
`Array`. For example:
|
204
220
|
|
205
221
|
```ruby
|
206
222
|
require 'props_template/core_ext'
|
207
|
-
data = [
|
223
|
+
data = [
|
224
|
+
{id: 1, name: 'foo'},
|
225
|
+
{id: 2, name: 'bar'}
|
226
|
+
]
|
208
227
|
|
209
228
|
json.posts
|
210
229
|
json.array! data do
|
@@ -213,28 +232,39 @@ json.posts
|
|
213
232
|
end
|
214
233
|
```
|
215
234
|
|
216
|
-
PropsTemplate does not know what the elements are in your collection. The
|
235
|
+
PropsTemplate does not know what the elements are in your collection. The
|
236
|
+
example above will be fine for [traversing](#traversing)
|
237
|
+
by index, but will raise a `NotImplementedError` if you query by attribute. You
|
238
|
+
may still need to implement `member_by`.
|
217
239
|
|
218
240
|
### json.deferred!
|
219
|
-
Returns all deferred nodes used by the [
|
241
|
+
Returns all deferred nodes used by the [deferment](#deferment) option.
|
242
|
+
|
243
|
+
**Note** This is a [BreezyJS][1] specific functionality and is used in
|
244
|
+
`application.json.props` when first running `rails breezy:install:web`
|
245
|
+
|
220
246
|
|
221
247
|
```ruby
|
222
248
|
json.deferred json.deferred!
|
249
|
+
|
250
|
+
# => [{url: '/some_url?bzq=outer.inner', path: 'outer.inner', type: 'auto'}]
|
223
251
|
```
|
224
252
|
|
225
|
-
This method
|
253
|
+
This method provides metadata about deferred nodes to the frontend ([BreezyJS][1])
|
254
|
+
to fetch missing data in a second round trip.
|
226
255
|
|
227
256
|
### json.fragments!
|
228
|
-
Returns all fragment nodes used by the [partial fragments](#partial-fragments)
|
257
|
+
Returns all fragment nodes used by the [partial fragments](#partial-fragments)
|
258
|
+
option.
|
229
259
|
|
230
|
-
```ruby
|
231
|
-
json.fragments json.fragments!
|
232
|
-
```
|
260
|
+
```ruby json.fragments json.fragments! ```
|
233
261
|
|
234
|
-
This
|
262
|
+
**Note** This is a [BreezyJS][1] specific functionality and is used in
|
263
|
+
`application.json.props` when first running `rails breezy:install:web`
|
235
264
|
|
236
265
|
## Options
|
237
|
-
Functionality such as Partials, Deferements, and Caching can only be
|
266
|
+
Options Functionality such as Partials, Deferements, and Caching can only be
|
267
|
+
set on a block. It is normal to see empty blocks.
|
238
268
|
|
239
269
|
```ruby
|
240
270
|
json.post(partial: 'blog_post') do
|
@@ -243,7 +273,9 @@ end
|
|
243
273
|
|
244
274
|
### Partials
|
245
275
|
|
246
|
-
Partials are supported. The following will render the file
|
276
|
+
Partials are supported. The following will render the file
|
277
|
+
`views/posts/_blog_posts.json.props`, and set a local variable `foo` assigned
|
278
|
+
with @post, which you can use inside the partial.
|
247
279
|
|
248
280
|
```ruby
|
249
281
|
json.one_post partial: ["posts/blog_post", locals: {post: @post}] do
|
@@ -253,7 +285,8 @@ end
|
|
253
285
|
Usage with arrays:
|
254
286
|
|
255
287
|
```ruby
|
256
|
-
#
|
288
|
+
# The `as:` option is supported when using `array!`
|
289
|
+
|
257
290
|
json.posts do
|
258
291
|
json.array! @posts, partial: ["posts/blog_post", locals: {foo: 'bar'}, as: 'post'] do
|
259
292
|
end
|
@@ -261,14 +294,14 @@ end
|
|
261
294
|
```
|
262
295
|
|
263
296
|
### Partial Fragments
|
297
|
+
**Note** This is a [BreezyJS][1] specific functionality.
|
264
298
|
|
265
|
-
A fragment
|
266
|
-
|
267
|
-
You would need use partials and add the option `fragment: true`.
|
299
|
+
A fragment identifies a partial output across multiple pages. It can be used to
|
300
|
+
update cross cutting concerns like a header bar.
|
268
301
|
|
269
302
|
```ruby
|
270
303
|
# index.json.props
|
271
|
-
json.header partial: ["profile", fragment:
|
304
|
+
json.header partial: ["profile", fragment: "header"] do
|
272
305
|
end
|
273
306
|
|
274
307
|
# _profile.json.props
|
@@ -282,21 +315,16 @@ end
|
|
282
315
|
When using fragments with Arrays, the argument **MUST** be a lamda:
|
283
316
|
|
284
317
|
```ruby
|
285
|
-
require 'props_template/core_ext'
|
286
|
-
|
287
|
-
json.array! ['foo', 'bar'], partial: ["footer", fragment: ->(x){ x == 'foo'}]
|
288
|
-
```
|
289
|
-
|
290
|
-
PropsTemplate creates a name for the partial using a digest of your locals, partial name, and globalId (to_json as fallback if there is no globalId) on objects that you pass. You may override this behavior and use a custom identifier:
|
318
|
+
require 'props_template/core_ext'
|
291
319
|
|
292
|
-
|
293
|
-
# index.js.breezy
|
294
|
-
json.header partial: ["profile", fragment: 'me_header'] do
|
320
|
+
json.array! ['foo', 'bar'], partial: ["footer", fragment: ->(x){ x == 'foo'}] do
|
295
321
|
end
|
296
322
|
```
|
297
323
|
|
298
324
|
### Caching
|
299
|
-
Caching is supported on
|
325
|
+
Caching is supported on internal nodes only. This limitation is what makes it
|
326
|
+
possible to for props_template to forgo marshalling/unmarshalling and simply
|
327
|
+
use [push_json](http://www.ohler.com/oj/doc/Oj/StringWriter.html#push_json-instance_method).
|
300
328
|
|
301
329
|
Usage:
|
302
330
|
|
@@ -322,44 +350,60 @@ end
|
|
322
350
|
When used with arrays, PropsTemplate will use `Rails.cache.read_multi`.
|
323
351
|
|
324
352
|
```ruby
|
325
|
-
require 'props_template/core_ext'
|
353
|
+
require 'props_template/core_ext'
|
354
|
+
|
355
|
+
opts = { cache: ->(i){ ['a', i] } }
|
326
356
|
|
327
|
-
opts = {
|
328
|
-
cache: ->(i){ ['a', i] }
|
329
|
-
}
|
330
357
|
json.array! [4,5], opts do |x|
|
331
358
|
json.top "hello" + x.to_s
|
332
359
|
end
|
333
360
|
|
334
361
|
#or on arrays with partials
|
335
362
|
|
336
|
-
opts = {
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
json.array! @options, opts
|
363
|
+
opts = { cache: (->(d){ ['a', d.id] }), partial: ["blog_post", as: :blog_post] }
|
364
|
+
|
365
|
+
json.array! @options, opts do
|
366
|
+
end
|
341
367
|
```
|
342
368
|
|
343
369
|
### Deferment
|
344
370
|
|
345
|
-
You can defer rendering of expensive nodes in your content tree using the
|
346
|
-
|
371
|
+
You can defer rendering of expensive nodes in your content tree using the
|
372
|
+
`defer: :manual` option. Behind the scenes PropsTemplates will no-op the block
|
373
|
+
entirely and replace the value with a placeholder. A common use case would be
|
374
|
+
tabbed content that does not load until you click the tab.
|
375
|
+
|
376
|
+
When your client receives the payload, you may issue a second request to the
|
377
|
+
same endpoint to fetch any missing nodes. See [traversing nodes](#traversing)
|
347
378
|
|
348
|
-
|
379
|
+
There is also an `defer: :auto` option that you can use with [BreezyJS][1]. [BreezyJS][1]
|
380
|
+
will use the metadata from `json.deferred!` to issue a `remote` dispatch to fetch
|
381
|
+
the missing node and immutably graft it at the appropriate keypath in your Redux
|
382
|
+
store.
|
349
383
|
|
350
384
|
Usage:
|
351
385
|
|
352
386
|
```ruby
|
353
|
-
json.dashboard(defer: :
|
387
|
+
json.dashboard(defer: :manual) do
|
388
|
+
sleep 10
|
389
|
+
json.some_fancy_metric 42
|
390
|
+
end
|
391
|
+
|
392
|
+
|
393
|
+
# or you can explicitly pass a placeholder
|
394
|
+
|
395
|
+
json.dashboard(defer: [:manual, placeholder: {}]) do
|
354
396
|
sleep 10
|
355
397
|
json.some_fancy_metric 42
|
356
398
|
end
|
357
399
|
```
|
358
400
|
|
359
|
-
A
|
401
|
+
A auto option is available:
|
402
|
+
|
403
|
+
**Note** This is a [BreezyJS][1] specific functionality.
|
360
404
|
|
361
405
|
```ruby
|
362
|
-
json.dashboard(defer: :
|
406
|
+
json.dashboard(defer: :auto) do
|
363
407
|
sleep 10
|
364
408
|
json.some_fancy_metric 42
|
365
409
|
end
|
@@ -371,39 +415,51 @@ Finally in your `application.json.props`:
|
|
371
415
|
json.defers json.deferred!
|
372
416
|
```
|
373
417
|
|
374
|
-
|
375
|
-
If `:manual` is used, PropsTemplate will no-op the block and will not populate `json.deferred!`. Its up to you to [query](props-template.md#traversing_nodes) to fetch the node seperately. A common usecase would be tab content that does not load until you click the tab.
|
376
|
-
|
377
418
|
#### Working with arrays
|
378
|
-
The default behavior for deferements is to use the index of the collection to
|
419
|
+
The default behavior for deferements is to use the index of the collection to
|
420
|
+
identify an element.
|
421
|
+
|
422
|
+
**Note** If you are using this library with [BreezyJS][1], the `:auto` options will
|
423
|
+
generate `?_bzq=a.b.c.0.title` for `json.deferred!`.
|
379
424
|
|
380
425
|
If you wish to use an attribute to identify the element. You must:
|
381
|
-
|
382
|
-
|
426
|
+
|
427
|
+
1. Use the `:key` option on `json.array!`. This key refers to an attribute on
|
428
|
+
your collection item, and is used for `defer: :auto` to generate a keypath for
|
429
|
+
[BreezyJS][1]. If you are NOT using BreezyJS, you do not need to do this.
|
430
|
+
|
431
|
+
2. Implement `member_at`, on the [collection](#jsonarray). This will be called
|
432
|
+
by PropsTemplate to when [searching nodes](#traversing)
|
383
433
|
|
384
434
|
For example:
|
385
435
|
|
386
436
|
```ruby
|
387
|
-
require 'props_template/core_ext'
|
388
|
-
|
389
|
-
|
437
|
+
require 'props_template/core_ext'
|
438
|
+
data = [
|
439
|
+
{id: 1, name: 'foo'},
|
440
|
+
{id: 2, name: 'bar'}
|
441
|
+
]
|
390
442
|
|
391
443
|
json.posts
|
392
444
|
json.array! data, key: :some_id do |item|
|
445
|
+
# By using :key, props_template will append `json.some_id item.some_id`
|
446
|
+
# automatically
|
447
|
+
|
393
448
|
json.contact(defer: :auto) do
|
394
449
|
json.address '123 example drive'
|
395
450
|
end
|
396
|
-
|
397
|
-
# json.some_id item.some_id will be appended automatically to the end of the block
|
398
451
|
end
|
399
452
|
end
|
400
453
|
```
|
401
454
|
|
402
|
-
|
455
|
+
If you are using [BreezyJS][1], BreezyJS will, it will automatically kick off
|
456
|
+
`remote(?bzq=posts.some_id=1.contact)` and `remote(?bzq=posts.some_id=2.contact)`.
|
403
457
|
|
404
|
-
|
458
|
+
## Traversing
|
405
459
|
|
406
|
-
PropsTemplate has the ability to walk the tree you build, skipping execution of
|
460
|
+
PropsTemplate has the ability to walk the tree you build, skipping execution of
|
461
|
+
untargeted nodes. This feature is useful for selectively updating your frontend
|
462
|
+
state.
|
407
463
|
|
408
464
|
```ruby
|
409
465
|
traversal_path = ['data', 'details', 'personal']
|
@@ -411,7 +467,7 @@ traversal_path = ['data', 'details', 'personal']
|
|
411
467
|
json.data(search: traversal_path) do
|
412
468
|
json.details do
|
413
469
|
json.employment do
|
414
|
-
...more stuff
|
470
|
+
...more stuff
|
415
471
|
end
|
416
472
|
|
417
473
|
json.personal do
|
@@ -422,25 +478,28 @@ json.data(search: traversal_path) do
|
|
422
478
|
end
|
423
479
|
|
424
480
|
json.footer do
|
425
|
-
|
481
|
+
...
|
426
482
|
end
|
427
483
|
```
|
428
484
|
|
429
|
-
PropsTemplate will
|
485
|
+
PropsTemplate will walk depth first, walking only when it finds a matching key,
|
486
|
+
then executes the associated block, and repeats until it the node is found.
|
487
|
+
The above will output:
|
430
488
|
|
431
489
|
```json
|
432
490
|
{
|
433
|
-
data: {
|
434
|
-
name: 'james',
|
435
|
-
zipCode: 91210
|
491
|
+
"data": {
|
492
|
+
"name": 'james',
|
493
|
+
"zipCode": 91210
|
436
494
|
},
|
437
|
-
footer: {
|
438
|
-
|
495
|
+
"footer": {
|
496
|
+
...
|
439
497
|
}
|
440
498
|
}
|
441
499
|
```
|
442
500
|
|
443
|
-
|
501
|
+
Searching only works with blocks, and will NOT work with Scalars
|
502
|
+
("leaf" values). For example:
|
444
503
|
|
445
504
|
```ruby
|
446
505
|
traversal_path = ['data', 'details', 'personal', 'name'] <- not found
|
@@ -452,12 +511,11 @@ json.data(search: traversal_path) do
|
|
452
511
|
end
|
453
512
|
end
|
454
513
|
end
|
455
|
-
|
456
514
|
```
|
457
515
|
|
458
516
|
## Nodes that do not exist
|
459
517
|
|
460
|
-
Nodes that are not found will
|
518
|
+
Nodes that are not found will remove the branch where search was enabled on.
|
461
519
|
|
462
520
|
```ruby
|
463
521
|
traversal_path = ['data', 'details', 'does_not_exist']
|
@@ -471,17 +529,54 @@ json.data(search: traversal_path) do
|
|
471
529
|
end
|
472
530
|
|
473
531
|
json.footer do
|
474
|
-
|
532
|
+
...
|
475
533
|
end
|
476
|
-
|
477
534
|
```
|
478
535
|
|
479
536
|
The above will render:
|
480
537
|
|
481
|
-
```
|
538
|
+
```json
|
482
539
|
{
|
483
|
-
footer: {
|
540
|
+
"footer": {
|
484
541
|
...
|
485
542
|
}
|
486
543
|
}
|
487
544
|
```
|
545
|
+
|
546
|
+
## Layouts
|
547
|
+
A single layout is supported. To use, create an `application.json.props` in
|
548
|
+
`app/views/layouts`. Here's an example:
|
549
|
+
|
550
|
+
```ruby
|
551
|
+
json.data do
|
552
|
+
# template runs here.
|
553
|
+
yield json
|
554
|
+
end
|
555
|
+
|
556
|
+
json.header do
|
557
|
+
json.greeting "Hello"
|
558
|
+
end
|
559
|
+
|
560
|
+
json.footer do
|
561
|
+
json.greeting "Hello"
|
562
|
+
end
|
563
|
+
|
564
|
+
json.flash flash.to_h
|
565
|
+
```
|
566
|
+
|
567
|
+
**NOTE** PropsTemplate inverts the usual Rails rendering flow. PropsTemplate
|
568
|
+
will render Layout first, then the template when `yield json` is used.
|
569
|
+
|
570
|
+
## Contributing
|
571
|
+
|
572
|
+
See the [CONTRIBUTING] document. Thank you, [contributors]!
|
573
|
+
|
574
|
+
[CONTRIBUTING]: CONTRIBUTING.md
|
575
|
+
[contributors]: https://github.com/thoughtbot/props_template/graphs/contributors
|
576
|
+
|
577
|
+
## Special Thanks
|
578
|
+
|
579
|
+
Thanks to [turbostreamer](https://github.com/malomalo/turbostreamer) for the
|
580
|
+
inspiration.
|
581
|
+
|
582
|
+
[1]: https://github.com/thoughtbot/breezy
|
data/lib/props_template.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: props_template
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Johny Ho
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -52,8 +52,10 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.9'
|
55
|
-
description:
|
56
|
-
|
55
|
+
description: PropsTemplate is a direct-to-Oj, JBuilder-like DSL for building JSON.
|
56
|
+
It has support for Russian-Doll caching, layouts, and can be queried by giving the
|
57
|
+
root a key path.
|
58
|
+
email: johny@thoughtbot.com
|
57
59
|
executables: []
|
58
60
|
extensions: []
|
59
61
|
extra_rdoc_files: []
|
@@ -74,10 +76,11 @@ files:
|
|
74
76
|
- lib/props_template/layout_patch.rb
|
75
77
|
- lib/props_template/railtie.rb
|
76
78
|
- lib/props_template/searcher.rb
|
79
|
+
- lib/props_template/version.rb
|
77
80
|
- spec/layout_spec.rb
|
78
81
|
- spec/props_template_spec.rb
|
79
82
|
- spec/searcher_spec.rb
|
80
|
-
homepage: https://github.com/
|
83
|
+
homepage: https://github.com/thoughtbot/props_template/
|
81
84
|
licenses:
|
82
85
|
- MIT
|
83
86
|
metadata: {}
|
@@ -89,17 +92,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
89
92
|
requirements:
|
90
93
|
- - ">="
|
91
94
|
- !ruby/object:Gem::Version
|
92
|
-
version: '2.
|
95
|
+
version: '2.5'
|
93
96
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
97
|
requirements:
|
95
98
|
- - ">="
|
96
99
|
- !ruby/object:Gem::Version
|
97
100
|
version: '0'
|
98
101
|
requirements: []
|
99
|
-
rubygems_version: 3.1.
|
102
|
+
rubygems_version: 3.1.6
|
100
103
|
signing_key:
|
101
104
|
specification_version: 4
|
102
|
-
summary: A JSON builder
|
105
|
+
summary: A fast JSON builder
|
103
106
|
test_files:
|
104
107
|
- spec/searcher_spec.rb
|
105
108
|
- spec/layout_spec.rb
|