props_template 1.0.0.alpha.3 → 1.0.0.alpha.4
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/README.md +56 -42
- data/lib/props_template/base.rb +17 -10
- data/lib/props_template/base_with_extensions.rb +8 -3
- data/lib/props_template/extension_manager.rb +1 -1
- data/lib/props_template/extensions/partial_renderer.rb +0 -1
- data/lib/props_template/helper.rb +7 -0
- data/lib/props_template/options.rb +39 -0
- data/lib/props_template/railtie.rb +1 -0
- data/lib/props_template/searcher.rb +2 -2
- data/lib/props_template/version.rb +1 -1
- data/lib/props_template.rb +3 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dd22916bd76997bbac899cc2c7f3ee1dde0de4d757d508bde300c665fefffed2
|
|
4
|
+
data.tar.gz: 3ed18e6266e026ba545b5389cd70ebd215e825be1aa268afd3510a1c695a633f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e036c21457b476fb4554d7d5e5420a88659da3767750eaa70cabc05bd8f5c6924d23aaeb7e76e3640bf8d05558c2b6ac8e1eed9e4cf437d8f19e3960495cb199
|
|
7
|
+
data.tar.gz: cc7a63fc308d9b3c5e3c3c49286cf7c69e06d76eca3d51c04255eebf68c8158f44d76768396b1f0750adc204d0cae75dc7bfeb1cebd14e806bf690b50013f02e
|
data/README.md
CHANGED
|
@@ -36,7 +36,7 @@ json.menu do
|
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
json.dashboard(defer:
|
|
39
|
+
json.dashboard(with.defer(:auto)) do
|
|
40
40
|
sleep 5
|
|
41
41
|
json.complexPostMetric 500
|
|
42
42
|
end
|
|
@@ -46,7 +46,7 @@ json.posts do
|
|
|
46
46
|
paged_posts = @posts.page(page_num).per(20)
|
|
47
47
|
|
|
48
48
|
json.list do
|
|
49
|
-
json.array! paged_posts,
|
|
49
|
+
json.array! paged_posts, with.id_key(:id) do |post|
|
|
50
50
|
json.id post.id
|
|
51
51
|
json.description post.description
|
|
52
52
|
json.commentsCount post.comments.count
|
|
@@ -59,8 +59,7 @@ json.posts do
|
|
|
59
59
|
json.total @posts.count
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
json.footer partial
|
|
63
|
-
end
|
|
62
|
+
json.footer with.partial('shared/footer')
|
|
64
63
|
```
|
|
65
64
|
|
|
66
65
|
## Installation
|
|
@@ -96,13 +95,13 @@ You can also add a [layout](#layouts).
|
|
|
96
95
|
Defines the attribute or structure. All keys are not formatted by default. See [Change Key Format](#change-key-format) to change this behavior.
|
|
97
96
|
|
|
98
97
|
```ruby
|
|
99
|
-
json.set! :authorDetails,
|
|
98
|
+
json.set! :authorDetails, with.some_option do
|
|
100
99
|
json.set! :firstName, 'David'
|
|
101
100
|
end
|
|
102
101
|
|
|
103
102
|
# or
|
|
104
103
|
|
|
105
|
-
json.authorDetails,
|
|
104
|
+
json.authorDetails, with.some_option do
|
|
106
105
|
json.firstName 'David'
|
|
107
106
|
end
|
|
108
107
|
|
|
@@ -115,7 +114,7 @@ The inline form defines key and value
|
|
|
115
114
|
| Parameter | Notes |
|
|
116
115
|
| :--- | :--- |
|
|
117
116
|
| key | A json object key|
|
|
118
|
-
| value | A value |
|
|
117
|
+
| value | A value or an [options][#options] object enabled with [partial](#partials)|
|
|
119
118
|
|
|
120
119
|
```ruby
|
|
121
120
|
|
|
@@ -133,7 +132,7 @@ The block form defines key and structure
|
|
|
133
132
|
| Parameter | Notes |
|
|
134
133
|
| :--- | :--- |
|
|
135
134
|
| key | A json object key|
|
|
136
|
-
| options | Additional [options](#options)|
|
|
135
|
+
| options | Additional hash [options](#options) or a [options](#options) object|
|
|
137
136
|
| block | Additional `json.set!`s or `json.array!`s|
|
|
138
137
|
|
|
139
138
|
```ruby
|
|
@@ -149,11 +148,12 @@ end
|
|
|
149
148
|
```
|
|
150
149
|
|
|
151
150
|
The difference between the block form and inline form is
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
151
|
+
|
|
152
|
+
1. Passing options as a [hash](#hash-options) is only available for the
|
|
153
|
+
block form (also called an internal node)
|
|
154
|
+
2. The inline form is considered a leaf node, if you need features like
|
|
155
|
+
partials you may use [options](#options) objects only.
|
|
156
|
+
3. Only internal nodes may dug for [digging](#digging)
|
|
157
157
|
|
|
158
158
|
### json.extract!
|
|
159
159
|
Extracts attributes from object or hash in 1 line
|
|
@@ -189,7 +189,7 @@ Generates an array of json objects.
|
|
|
189
189
|
collection = [ {name: 'john'}, {name: 'jim'} ]
|
|
190
190
|
|
|
191
191
|
json.details do
|
|
192
|
-
json.array! collection,
|
|
192
|
+
json.array! collection, with.some_option do |person|
|
|
193
193
|
json.firstName person[:name]
|
|
194
194
|
end
|
|
195
195
|
end
|
|
@@ -306,11 +306,29 @@ option.
|
|
|
306
306
|
`application.json.props` when first running `rails superglue:install:web`
|
|
307
307
|
|
|
308
308
|
## Options
|
|
309
|
-
|
|
310
|
-
|
|
309
|
+
|
|
310
|
+
PropsTemplate provides a `with` helper to build a `Props::Option` object that enable
|
|
311
|
+
functionality such as Partials, Deferments, and Caching
|
|
312
|
+
|
|
313
|
+
The following are equivalent:
|
|
314
|
+
|
|
315
|
+
```ruby
|
|
316
|
+
json.post(with.partial('blog_post')
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
or
|
|
320
|
+
|
|
321
|
+
```ruby
|
|
322
|
+
json.post(Props::Options.new.partial('blog_post')
|
|
323
|
+
```
|
|
324
|
+
### Hash options
|
|
325
|
+
|
|
326
|
+
Previously, a normal hash was supported for internal nodes as long as an empty
|
|
327
|
+
block accompanied the option. This option is still supported, but its
|
|
328
|
+
recommended to use the `with` option builder.
|
|
311
329
|
|
|
312
330
|
```ruby
|
|
313
|
-
json.post(partial: 'blog_post') do
|
|
331
|
+
json.post(partial: 'blog_post', locals: {post: @post}) do
|
|
314
332
|
end
|
|
315
333
|
```
|
|
316
334
|
|
|
@@ -321,8 +339,7 @@ Partials are supported. The following will render the file
|
|
|
321
339
|
with @post, which you can use inside the partial.
|
|
322
340
|
|
|
323
341
|
```ruby
|
|
324
|
-
json.one_post
|
|
325
|
-
end
|
|
342
|
+
json.one_post(with.partial("posts/blog_post", locals: {post: @post}))
|
|
326
343
|
```
|
|
327
344
|
|
|
328
345
|
Usage with arrays:
|
|
@@ -332,8 +349,7 @@ Usage with arrays:
|
|
|
332
349
|
# Without `as:` option you can use blog_post variable (name is based on partial's name) inside partial
|
|
333
350
|
|
|
334
351
|
json.posts do
|
|
335
|
-
json.array! @posts, partial
|
|
336
|
-
end
|
|
352
|
+
json.array! @posts, with.partial("posts/blog_post", locals: {foo: 'bar'}, as: 'post')
|
|
337
353
|
end
|
|
338
354
|
```
|
|
339
355
|
|
|
@@ -344,16 +360,14 @@ cause performance problems. It's best used for things like a shared header or fo
|
|
|
344
360
|
Do:
|
|
345
361
|
|
|
346
362
|
```ruby
|
|
347
|
-
json.partial! partial
|
|
348
|
-
end
|
|
363
|
+
json.partial! with.partial("header", locals: {user: @user})
|
|
349
364
|
```
|
|
350
365
|
|
|
351
366
|
or
|
|
352
367
|
|
|
353
368
|
```ruby
|
|
354
369
|
json.posts do
|
|
355
|
-
json.array! @posts, partial
|
|
356
|
-
end
|
|
370
|
+
json.array! @posts, with.partial("posts/blog_post", locals: {post: @post})
|
|
357
371
|
end
|
|
358
372
|
```
|
|
359
373
|
|
|
@@ -374,8 +388,7 @@ update cross cutting concerns like a header bar.
|
|
|
374
388
|
|
|
375
389
|
```ruby
|
|
376
390
|
# index.json.props
|
|
377
|
-
json.header partial
|
|
378
|
-
end
|
|
391
|
+
json.header with.partial("profile").fragment("header")
|
|
379
392
|
|
|
380
393
|
# _profile.json.props
|
|
381
394
|
json.profile do
|
|
@@ -390,8 +403,7 @@ When using fragments with Arrays, the argument **MUST** be a lamda:
|
|
|
390
403
|
```ruby
|
|
391
404
|
require 'props_template/core_ext'
|
|
392
405
|
|
|
393
|
-
json.array! ['foo', 'bar'], partial
|
|
394
|
-
end
|
|
406
|
+
json.array! ['foo', 'bar'], with.partial("footer").fragment(->(x){ x == 'foo'})
|
|
395
407
|
```
|
|
396
408
|
|
|
397
409
|
### Caching
|
|
@@ -402,19 +414,18 @@ use [push_json](http://www.ohler.com/oj/doc/Oj/StringWriter.html#push_json-insta
|
|
|
402
414
|
Usage:
|
|
403
415
|
|
|
404
416
|
```ruby
|
|
405
|
-
json.author(cache
|
|
417
|
+
json.author(with.cache("some_cache_key")) do
|
|
406
418
|
json.firstName "tommy"
|
|
407
419
|
end
|
|
408
420
|
|
|
409
421
|
# or
|
|
410
422
|
|
|
411
|
-
json.profile(cache
|
|
412
|
-
end
|
|
423
|
+
json.profile(with.cache("cachekey").partial("profile", locals: {foo: 1}))
|
|
413
424
|
|
|
414
425
|
# or nest it
|
|
415
426
|
|
|
416
|
-
json.author(cache
|
|
417
|
-
json.address(cache
|
|
427
|
+
json.author(with.cache("some_cache_key")) do
|
|
428
|
+
json.address(with.cache("some_other_cache_key")) do
|
|
418
429
|
json.zip 11214
|
|
419
430
|
end
|
|
420
431
|
end
|
|
@@ -425,7 +436,7 @@ When used with arrays, PropsTemplate will use `Rails.cache.read_multi`.
|
|
|
425
436
|
```ruby
|
|
426
437
|
require 'props_template/core_ext'
|
|
427
438
|
|
|
428
|
-
opts =
|
|
439
|
+
opts = with.cache(->(i){ ['a', i] } )
|
|
429
440
|
|
|
430
441
|
json.array! [4,5], opts do |x|
|
|
431
442
|
json.top "hello" + x.to_s
|
|
@@ -433,7 +444,7 @@ end
|
|
|
433
444
|
|
|
434
445
|
# or on arrays with partials
|
|
435
446
|
|
|
436
|
-
opts =
|
|
447
|
+
opts = with.cache(->(d){ ['a', d.id] }).partial("blog_post", as: :blog_post)
|
|
437
448
|
|
|
438
449
|
json.array! @options, opts do
|
|
439
450
|
end
|
|
@@ -457,7 +468,7 @@ store.
|
|
|
457
468
|
Usage:
|
|
458
469
|
|
|
459
470
|
```ruby
|
|
460
|
-
json.dashboard(defer:
|
|
471
|
+
json.dashboard(with.defer(:manual)) do
|
|
461
472
|
sleep 10
|
|
462
473
|
json.someFancyMetric 42
|
|
463
474
|
end
|
|
@@ -465,7 +476,7 @@ end
|
|
|
465
476
|
|
|
466
477
|
# or you can explicitly pass a placeholder
|
|
467
478
|
|
|
468
|
-
json.dashboard(defer:
|
|
479
|
+
json.dashboard(with.defer(:manual, placeholder: {})) do
|
|
469
480
|
sleep 10
|
|
470
481
|
json.someFancyMetric 42
|
|
471
482
|
end
|
|
@@ -476,7 +487,7 @@ A auto option is available:
|
|
|
476
487
|
**Note** This is a [SuperglueJS][1] specific functionality.
|
|
477
488
|
|
|
478
489
|
```ruby
|
|
479
|
-
json.dashboard(defer:
|
|
490
|
+
json.dashboard(with.defer(:auto)) do
|
|
480
491
|
sleep 10
|
|
481
492
|
json.someFancyMetric 42
|
|
482
493
|
end
|
|
@@ -514,11 +525,11 @@ data = [
|
|
|
514
525
|
]
|
|
515
526
|
|
|
516
527
|
json.posts
|
|
517
|
-
json.array! data,
|
|
528
|
+
json.array! data, with.id_key(:some_id) do |item|
|
|
518
529
|
# By using :key, props_template will append `json.some_id item.some_id`
|
|
519
530
|
# automatically
|
|
520
531
|
|
|
521
|
-
json.contact(defer:
|
|
532
|
+
json.contact(with.defer(:auto)) do
|
|
522
533
|
json.address '123 example drive'
|
|
523
534
|
end
|
|
524
535
|
end
|
|
@@ -623,7 +634,10 @@ A single layout is supported. To use, create an `application.json.props` in
|
|
|
623
634
|
```ruby
|
|
624
635
|
json.data do
|
|
625
636
|
# template runs here.
|
|
626
|
-
|
|
637
|
+
_.call(json)
|
|
638
|
+
# NOTE: you can also use `yield json` instead, but prism sees this as
|
|
639
|
+
# a syntax error, so the `_.call(json)` is a workaround.
|
|
640
|
+
# See: https://github.com/thoughtbot/props_template/issues/58
|
|
627
641
|
end
|
|
628
642
|
|
|
629
643
|
json.header do
|
data/lib/props_template/base.rb
CHANGED
|
@@ -14,7 +14,7 @@ module Props
|
|
|
14
14
|
@scope = nil
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def
|
|
17
|
+
def set_content!(options = {})
|
|
18
18
|
@scope = nil
|
|
19
19
|
yield
|
|
20
20
|
if @scope.nil?
|
|
@@ -26,7 +26,7 @@ module Props
|
|
|
26
26
|
def handle_set_block(key, options)
|
|
27
27
|
key = format_key(key)
|
|
28
28
|
@stream.push_key(key)
|
|
29
|
-
|
|
29
|
+
set_content!(options) do
|
|
30
30
|
yield
|
|
31
31
|
end
|
|
32
32
|
end
|
|
@@ -64,7 +64,7 @@ module Props
|
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
def handle_collection_item(collection, item, index, options)
|
|
67
|
-
|
|
67
|
+
set_content!(options) do
|
|
68
68
|
yield
|
|
69
69
|
end
|
|
70
70
|
end
|
|
@@ -97,13 +97,20 @@ module Props
|
|
|
97
97
|
raise InvalidScopeForArrayError.new("array! expects exclusive use of this block")
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
-
if
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
100
|
+
if block_given?
|
|
101
|
+
if collection.nil?
|
|
102
|
+
@child_index = nil
|
|
103
|
+
yield
|
|
104
|
+
else
|
|
105
|
+
handle_collection(collection, options) do |item, index|
|
|
106
|
+
yield item, index
|
|
107
|
+
end
|
|
106
108
|
end
|
|
109
|
+
elsif options.is_a?(Props::Options)
|
|
110
|
+
options.valid_for_set!
|
|
111
|
+
handle_collection(collection, options) {}
|
|
112
|
+
else
|
|
113
|
+
raise ArgumentError.new("array! requires a block when no Props::Options object is given")
|
|
107
114
|
end
|
|
108
115
|
|
|
109
116
|
@scope = :array
|
|
@@ -147,7 +154,7 @@ module Props
|
|
|
147
154
|
child_index += 1
|
|
148
155
|
|
|
149
156
|
# this changes the scope to nil so child in a child will break
|
|
150
|
-
|
|
157
|
+
set_content!(options) do
|
|
151
158
|
yield
|
|
152
159
|
end
|
|
153
160
|
|
|
@@ -26,7 +26,7 @@ module Props
|
|
|
26
26
|
@traveled_path.join(".")
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
def
|
|
29
|
+
def set_content!(options = {})
|
|
30
30
|
return super if !@em.has_extensions(options)
|
|
31
31
|
|
|
32
32
|
@em.handle(options) do
|
|
@@ -51,11 +51,16 @@ module Props
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def set!(key, options = {}, &block)
|
|
54
|
-
if block
|
|
54
|
+
if block || options.is_a?(Props::Options)
|
|
55
55
|
options = @em.refine_options(options)
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
if !block && options.is_a?(Props::Options)
|
|
59
|
+
options.valid_for_set!
|
|
60
|
+
super {}
|
|
61
|
+
else
|
|
62
|
+
super
|
|
63
|
+
end
|
|
59
64
|
end
|
|
60
65
|
|
|
61
66
|
def handle_set_block(key, options)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Props
|
|
2
|
+
class Options < Hash
|
|
3
|
+
class InvalidOptionError < StandardError; end
|
|
4
|
+
|
|
5
|
+
def partial(partial_name, opts = {})
|
|
6
|
+
self[:partial] = [partial_name, opts]
|
|
7
|
+
self
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def defer(type, placeholder: {}, **opts)
|
|
11
|
+
self[:defer] = [type, {placeholder: placeholder}.merge(opts)]
|
|
12
|
+
self
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def fragment(fragment)
|
|
16
|
+
raise "Fragment can't be defined without a partial. Please use `partial` first" if !self[:partial]
|
|
17
|
+
|
|
18
|
+
self[:partial][1][:fragment] = fragment
|
|
19
|
+
self
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def cache(id_or_block)
|
|
23
|
+
return unless id_or_block
|
|
24
|
+
|
|
25
|
+
self[:cache] = id_or_block
|
|
26
|
+
self
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def id_key(key_name)
|
|
30
|
+
self[:key] = key_name
|
|
31
|
+
self
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def valid_for_set!
|
|
35
|
+
raise InvalidOptionError.new("Props::Options can't be empty") if empty?
|
|
36
|
+
raise InvalidOptionError.new("The partial option must be used with an inline `set!`") if !key?(:partial)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -6,6 +6,7 @@ module Props
|
|
|
6
6
|
initializer :props_template do
|
|
7
7
|
ActiveSupport.on_load :action_view do
|
|
8
8
|
ActionView::Template.register_template_handler :props, Props::Handler
|
|
9
|
+
ActionView::Base.include Props::Helper
|
|
9
10
|
require "props_template/dependency_tracker"
|
|
10
11
|
require "props_template/layout_patch"
|
|
11
12
|
require "props_template/partial_patch"
|
|
@@ -41,12 +41,12 @@ module Props
|
|
|
41
41
|
[@found_block, @traveled_path, pass_opts, @fragment_path, fragment_context]
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
def
|
|
44
|
+
def set_content!(*args)
|
|
45
45
|
yield
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def set!(key, options = {}, &block)
|
|
49
|
-
return if @found_block || !block
|
|
49
|
+
return if @found_block || !block && !options.is_a?(Props::Options)
|
|
50
50
|
|
|
51
51
|
if @search_path[@depth] == key.to_s
|
|
52
52
|
@traveled_path.push(key)
|
data/lib/props_template.rb
CHANGED
|
@@ -9,6 +9,8 @@ require "active_support/core_ext/string/output_safety"
|
|
|
9
9
|
require "active_support/core_ext/array"
|
|
10
10
|
require "props_template/searcher"
|
|
11
11
|
require "props_template/handler"
|
|
12
|
+
require "props_template/options"
|
|
13
|
+
require "props_template/helper"
|
|
12
14
|
require "props_template/version"
|
|
13
15
|
|
|
14
16
|
require "active_support"
|
|
@@ -28,7 +30,7 @@ module Props
|
|
|
28
30
|
:deferred!,
|
|
29
31
|
:fragments!,
|
|
30
32
|
:disable_deferments!,
|
|
31
|
-
:
|
|
33
|
+
:set_content!,
|
|
32
34
|
:traveled_path!,
|
|
33
35
|
:fragment_context!,
|
|
34
36
|
to: :builder!
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: props_template
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.0.alpha.
|
|
4
|
+
version: 1.0.0.alpha.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Johny Ho
|
|
@@ -83,7 +83,9 @@ files:
|
|
|
83
83
|
- lib/props_template/extensions/fragment.rb
|
|
84
84
|
- lib/props_template/extensions/partial_renderer.rb
|
|
85
85
|
- lib/props_template/handler.rb
|
|
86
|
+
- lib/props_template/helper.rb
|
|
86
87
|
- lib/props_template/layout_patch.rb
|
|
88
|
+
- lib/props_template/options.rb
|
|
87
89
|
- lib/props_template/partial_patch.rb
|
|
88
90
|
- lib/props_template/railtie.rb
|
|
89
91
|
- lib/props_template/searcher.rb
|