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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47eaa94bedc38645ef945eb7308cdc257497b063b5a9df481d491ec3bb1ae3ca
4
- data.tar.gz: 48da4764807eb7924b224e98175f81c822a67e6ead927904df452d620d39e6e0
3
+ metadata.gz: dd22916bd76997bbac899cc2c7f3ee1dde0de4d757d508bde300c665fefffed2
4
+ data.tar.gz: 3ed18e6266e026ba545b5389cd70ebd215e825be1aa268afd3510a1c695a633f
5
5
  SHA512:
6
- metadata.gz: 40c1e3bfc2c99a3b37834abec4e9b8463d4585203583f9f2f7ba710d775e714a7950bf1bf60f9d86b67c34de6742a5b5a0d249e0154fb50736288123e9ebb1e4
7
- data.tar.gz: 70953db156e838cf72b220f9549c3a4abc6684d5bf0b0ad8a6305b15abf56cd1bd876635248fa2c8f1e43f21241475716d1dca49605fe65279951a8f2e59ed84
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: :auto) do
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, key: :id do |post|
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: 'shared/footer' do
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, {...options} do
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, {...options} do
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
- 1. The block form is an internal node. Functionality such as Partials,
153
- Deferment and other [options](#options) are only available on the
154
- block form.
155
- 2. The inline form is considered a leaf node, and you can only [dig](#digging)
156
- for internal nodes.
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, {...options} do |person|
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
- Options Functionality such as Partials, Deferments, and Caching can only be
310
- set on a block. It is normal to see empty blocks.
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 partial: ["posts/blog_post", locals: {post: @post}] do
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: ["posts/blog_post", locals: {foo: 'bar'}, as: 'post'] do
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: "header", locals: {user: @user} do
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: ["posts/blog_post", locals: {post: @post}] do
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: ["profile", fragment: "header"] do
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: ["footer", fragment: ->(x){ x == 'foo'}] do
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: "some_cache_key") do
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: "cachekey", partial: ["profile", locals: {foo: 1}]) do
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: "some_cache_key") do
417
- json.address(cache: "some_other_cache_key") do
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 = { cache: ->(i){ ['a', i] } }
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 = { cache: (->(d){ ['a', d.id] }), partial: ["blog_post", as: :blog_post] }
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: :manual) do
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: [:manual, placeholder: {}]) do
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: :auto) do
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, key: :some_id do |item|
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: :auto) do
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
- yield json
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
@@ -14,7 +14,7 @@ module Props
14
14
  @scope = nil
15
15
  end
16
16
 
17
- def set_block_content!(options = {})
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
- set_block_content!(options) do
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
- set_block_content!(options) do
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 collection.nil?
101
- @child_index = nil
102
- yield
103
- else
104
- handle_collection(collection, options) do |item, index|
105
- yield item, index
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
- set_block_content!(options) do
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 set_block_content!(options = {})
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
- super
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)
@@ -53,7 +53,7 @@ module Props
53
53
  @fragment.handle(options)
54
54
  else
55
55
  handle_cache(options) do
56
- base.set_block_content! do
56
+ base.set_content! do
57
57
  if options[:partial]
58
58
  @fragment.handle(options)
59
59
  @partialer.handle(options)
@@ -167,4 +167,3 @@ module Props
167
167
  end
168
168
  end
169
169
  end
170
-
@@ -0,0 +1,7 @@
1
+ module Props
2
+ module Helper
3
+ def with
4
+ Props::Options.new
5
+ end
6
+ end
7
+ end
@@ -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 set_block_content!(*args)
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)
@@ -1,3 +1,3 @@
1
1
  module Props
2
- VERSION = "1.0.0.alpha.3".freeze
2
+ VERSION = "1.0.0.alpha.4".freeze
3
3
  end
@@ -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
- :set_block_content!,
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.3
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