props_template 0.34.0 → 0.36.0

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: a4bda132d64b759a038cef1cef91f33ce8d2b839c6dfc2178f4b878772c60001
4
- data.tar.gz: 2774815590c928cd0b3d01a3d043f74b41086b44e9cd9e5d2947b3fbc44aeeab
3
+ metadata.gz: '01825cc9ebfc4584469c98d5f8e9df4eb8461210b9eb7fce104ff9ed484c2fa0'
4
+ data.tar.gz: 392c600764ec2c4de0a0d0035c2d7c573e7bc19f071f0e2efd2b6a66d3e862bc
5
5
  SHA512:
6
- metadata.gz: 34da08613e5545076e112105483fe1c2a6f851a730ffd126f48834bf08103385a31c9bff04190753bbfb1ccc55a631b5014d97f94c02f0bd097964bd3ad125a6
7
- data.tar.gz: b0a945bc75fe63b7bc08efc64e7b4de70093ff10c298bb0f5c9f80cf828cc33211553a2bdcc0aed5a0336f7d8a6580e96c126c4c745a8a350b4ec81abf74418b
6
+ metadata.gz: cb079a592e94c1d85ca7bed68d334e3c39939652473ae9779ca92bd4cf76311fcca9f3e5603da198b5274e55cd49a54120a554c8968a76bea01141228d0d6abc
7
+ data.tar.gz: 6e3ada0a21fc1f1112bd5d0839d229b3bf673a79e96386af58d0ee6a4cbf5978081b9d1cc2ba84e98ad7a4f24430fa5eb1ecd11d54ae78fdc15e28ab68df23c0
data/README.md CHANGED
@@ -93,8 +93,7 @@ You can also add a [layout](#layouts).
93
93
 
94
94
  ### json.set! or json.\<your key here\>
95
95
 
96
- Defines the attribute or structure. All keys are automatically camelized lower
97
- by default. See [Change Key Format](#change-key-format) to change this behavior.
96
+ Defines the attribute or structure. All keys are not formatted by default. See [Change Key Format](#change-key-format) to change this behavior.
98
97
 
99
98
  ```ruby
100
99
  json.set! :authorDetails, {...options} do
@@ -156,6 +155,33 @@ The difference between the block form and inline form is
156
155
  2. The inline form is considered a leaf node, and you can only [search](#traversing)
157
156
  for internal nodes.
158
157
 
158
+ ### json.extract!
159
+ Extracts attributes from object or hash in 1 line
160
+
161
+ ```ruby
162
+ # without extract!
163
+ json.id user.id
164
+ json.email user.email
165
+ json.firstName user.first_name
166
+
167
+ # with extract!
168
+ json.extract! user, :id, :email, :first_name
169
+
170
+ # => {"id" => 1, "email" => "email@gmail.com", "first_name" => "user"}
171
+
172
+ # with extract! with key transformation
173
+ json.extract! user, :id, [:first_name, :firstName], [:last_name, :lastName]
174
+
175
+ # => {"id" => 1, "firstName" => "user", "lastName" => "last"}
176
+ ```
177
+
178
+ The inline form defines object and attributes
179
+
180
+ | Parameter | Notes |
181
+ | :--- | :--- |
182
+ | object | An object |
183
+ | attributes | A list of attributes |
184
+
159
185
  ### json.array!
160
186
  Generates an array of json objects.
161
187
 
@@ -291,7 +317,7 @@ end
291
317
  ### Partials
292
318
 
293
319
  Partials are supported. The following will render the file
294
- `views/posts/_blog_posts.json.props`, and set a local variable `foo` assigned
320
+ `views/posts/_blog_posts.json.props`, and set a local variable `post` assigned
295
321
  with @post, which you can use inside the partial.
296
322
 
297
323
  ```ruby
@@ -303,6 +329,7 @@ Usage with arrays:
303
329
 
304
330
  ```ruby
305
331
  # The `as:` option is supported when using `array!`
332
+ # Without `as:` option you can use blog_post variable (name is based on partial's name) inside partial
306
333
 
307
334
  json.posts do
308
335
  json.array! @posts, partial: ["posts/blog_post", locals: {foo: 'bar'}, as: 'post'] do
@@ -310,6 +337,35 @@ json.posts do
310
337
  end
311
338
  ```
312
339
 
340
+ Rendering partials without a key is also supported using `json.partial!`, but use
341
+ sparingly! `json.partial!` is not optimized for collection rendering and may
342
+ cause performance problems. Its best used for things like a shared header or footer.
343
+
344
+ Do:
345
+
346
+ ```ruby
347
+ json.partial! partial: "header", locals: {user: @user} do
348
+ end
349
+ ```
350
+
351
+ or
352
+
353
+ ```ruby
354
+ json.posts do
355
+ json.array! @posts, partial: ["posts/blog_post", locals: {post: @post}] do
356
+ end
357
+ end
358
+ ```
359
+
360
+ Do NOT:
361
+
362
+ ```
363
+ @post.each do |post|
364
+ json.partial! partial: "post", locals: {post: @post} do
365
+ end
366
+ end
367
+ ```
368
+
313
369
  ### Partial Fragments
314
370
  **Note** This is a [SuperglueJS][1] specific functionality.
315
371
 
@@ -585,15 +641,60 @@ json.flash flash.to_h
585
641
  will render Layout first, then the template when `yield json` is used.
586
642
 
587
643
  ## Change key format
588
- By default, keys are not formatted. If you want to change this behavior,
589
- override it in an initializer:
644
+ By default, keys are not formatted. This is intentional. By being explicity with your keys,
645
+ it makes your views quicker and more easily searchable when working in Javascript land.
646
+
647
+ If you must change this behavior, override it in an initializer and cache the value:
590
648
 
591
649
  ```ruby
650
+ # default behavior
592
651
  Props::BaseWithExtensions.class_eval do
652
+ # json.firstValue "first"
653
+ # json.second_value "second"
654
+ #
655
+ # -> { "firstValue" => "first", "second_value" => "second" }
593
656
  def key_format(key)
594
657
  key.to_s
595
658
  end
596
659
  end
660
+
661
+ # camelCased behavior
662
+ Props::BaseWithExtensions.class_eval do
663
+ # json.firstValue "first"
664
+ # json.second_value "second"
665
+ #
666
+ # -> { "firstValue" => "first", "secondValue" => "second" }
667
+ def key_format(key)
668
+ @key_cache ||= {}
669
+ @key_cache[key] ||= key.to_s.camelize(:lower)
670
+ @key_cache[key]
671
+ end
672
+
673
+ def result!
674
+ result = super
675
+ @key_cache = {}
676
+ result
677
+ end
678
+ end
679
+
680
+ # snake_cased behavior
681
+ Props::BaseWithExtensions.class_eval do
682
+ # json.firstValue "first"
683
+ # json.second_value "second"
684
+ #
685
+ # -> { "first_value" => "first", "second_value" => "second" }
686
+ def key_format(key)
687
+ @key_cache ||= {}
688
+ @key_cache[key] ||= key.to_s.underscore
689
+ @key_cache[key]
690
+ end
691
+
692
+ def result!
693
+ result = super
694
+ @key_cache = {}
695
+ result
696
+ end
697
+ end
597
698
  ```
598
699
 
599
700
  ## Escape mode
@@ -105,6 +105,32 @@ module Props
105
105
  nil
106
106
  end
107
107
 
108
+ def partial!(**options)
109
+ @context.render options
110
+ end
111
+
112
+ # json.id item.id
113
+ # json.value item.value
114
+ #
115
+ # json.extract! item, :id, :value
116
+ #
117
+ # with key transformation
118
+ # json.extract! item, :id, [:first_name, :firstName]
119
+ def extract!(object, *values)
120
+ values.each do |value|
121
+ key, attribute = if value.is_a?(Array)
122
+ [value[1], value[0]]
123
+ else
124
+ [value, value]
125
+ end
126
+
127
+ set!(
128
+ key,
129
+ object.is_a?(Hash) ? object.fetch(attribute) : object.public_send(attribute)
130
+ )
131
+ end
132
+ end
133
+
108
134
  def result!
109
135
  if @scope.nil?
110
136
  @stream.push_object
@@ -82,7 +82,7 @@ module Props
82
82
  pass_opts[:locals] ||= {}
83
83
  pass_opts[:partial] = partial
84
84
  pass_opts[:formats] = [:json]
85
- pass_opts.delete(:handlers)
85
+ pass_opts[:handlers] = [:props]
86
86
 
87
87
  if !(String === partial)
88
88
  raise ArgumentError.new(INVALID_PARTIAL_MESSAGE % partial.inspect)
@@ -137,7 +137,7 @@ module Props
137
137
 
138
138
  partial, rest = [*options[:partial]]
139
139
  rest = (rest || {}).clone
140
- locals = rest[:locals] || {}
140
+ locals = (rest[:locals] || {}).clone
141
141
  rest[:locals] = locals
142
142
 
143
143
  if item
@@ -1,3 +1,3 @@
1
1
  module Props
2
- VERSION = "0.34.0".freeze
2
+ VERSION = "0.36.0".freeze
3
3
  end
@@ -22,6 +22,8 @@ module Props
22
22
  self.template_lookup_options = {handlers: [:props]}
23
23
 
24
24
  delegate :result!, :array!,
25
+ :partial!,
26
+ :extract!,
25
27
  :deferred!,
26
28
  :fragments!,
27
29
  :set_block_content!,
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.34.0
4
+ version: 0.36.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: 2024-05-31 00:00:00.000000000 Z
11
+ date: 2024-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport