props_template 1.0.0.alpha → 1.0.0.alpha.3

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: 1d2ef9c553bd49fd4d2a66bd8c2fc427e944b696c9eaa75f6224b5fb3627ca5e
4
- data.tar.gz: a717254c4c10d35fb871c50476e72273a25b3ee1ab55ce239b2660633443dbef
3
+ metadata.gz: 47eaa94bedc38645ef945eb7308cdc257497b063b5a9df481d491ec3bb1ae3ca
4
+ data.tar.gz: 48da4764807eb7924b224e98175f81c822a67e6ead927904df452d620d39e6e0
5
5
  SHA512:
6
- metadata.gz: 2a4ab324d50d6f14783b10405073e4cef4b80b70bebda2ce9e586927e79c3ea254cc6fd542ac1b5ea195ebb5d106ffde0fa2801a0215a917d10c32425146ec58
7
- data.tar.gz: 2d04b6d02c08da88ac66f5d61c782a8de35e27552f1a49402a39bf14814593b755d8b785f30b42a9dea4197bbe199581f79fcca2b6641293f18d604d48297aa7
6
+ metadata.gz: 40c1e3bfc2c99a3b37834abec4e9b8463d4585203583f9f2f7ba710d775e714a7950bf1bf60f9d86b67c34de6742a5b5a0d249e0154fb50736288123e9ebb1e4
7
+ data.tar.gz: 70953db156e838cf72b220f9549c3a4abc6684d5bf0b0ad8a6305b15abf56cd1bd876635248fa2c8f1e43f21241475716d1dca49605fe65279951a8f2e59ed84
data/README.md CHANGED
@@ -640,6 +640,28 @@ json.flash flash.to_h
640
640
  **NOTE** PropsTemplate inverts the usual Rails rendering flow. PropsTemplate
641
641
  will render Layout first, then the template when `yield json` is used.
642
642
 
643
+
644
+ ### Layouts in API-only Rails apps
645
+
646
+ If your controllers inherit from `ActionController::API` (typical in API-only Rails apps),
647
+ the layout feature won’t work out of the box, because `ActionController::API`
648
+ does not include layout support.
649
+
650
+ To enable layout rendering, you can include `ActionView::Layouts` manually,
651
+ then use `layout "your_own_layout"` as usual:
652
+
653
+ ```ruby
654
+ module Api
655
+ class BaseController < ActionController::API
656
+ include ActionView::Layouts
657
+
658
+ layout "api"
659
+ end
660
+ end
661
+ ```
662
+
663
+ Without this, Rails will silently skip the layout, which can be tricky to notice.
664
+
643
665
  ## Change key format
644
666
  By default, keys are not formatted. This is intentional. By being explicit with your keys,
645
667
  it makes your views quicker and more easily diggable when working in JavaScript land.
@@ -111,10 +111,6 @@ module Props
111
111
  nil
112
112
  end
113
113
 
114
- def partial!(**options)
115
- @context.render options
116
- end
117
-
118
114
  # json.id item.id
119
115
  # json.value item.value
120
116
  #
@@ -55,15 +55,16 @@ module Props
55
55
  options = @em.refine_options(options)
56
56
  end
57
57
 
58
- super(key, options, &block)
58
+ super
59
59
  end
60
60
 
61
61
  def handle_set_block(key, options)
62
- @traveled_path.push(key)
63
62
  n = 1
64
63
  if (suffix = options[:path_suffix])
65
64
  n += suffix.length
66
65
  @traveled_path.push(suffix)
66
+ else
67
+ @traveled_path.push(key)
67
68
  end
68
69
 
69
70
  super
@@ -7,18 +7,28 @@ module Props
7
7
  @fragments = fragments
8
8
  end
9
9
 
10
- def handle(options)
10
+ def self.fragment_name_from_options(options)
11
11
  return if !options[:partial]
12
- _partial_name, partial_opts = options[:partial]
12
+
13
+ _, partial_opts = [*options[:partial]]
14
+ return unless partial_opts
15
+
13
16
  fragment = partial_opts[:fragment]
14
17
 
15
18
  if String === fragment || Symbol === fragment
16
- key = fragment.to_s
17
- path = @base.traveled_path.join(".")
18
- @name =key
19
+ fragment.to_s
20
+ end
21
+ end
22
+
23
+ def handle(options)
24
+ fragment_name = self.class.fragment_name_from_options(options)
25
+ path = @base.traveled_path
26
+ .map { |item| item.is_a?(Array) ? item[0] : item }
27
+ .join(".")
19
28
 
29
+ if fragment_name
20
30
  @fragments.push(
21
- {id: key, path: path}
31
+ {id: fragment_name, path: path}
22
32
  )
23
33
  end
24
34
  end
@@ -3,7 +3,7 @@ module Props
3
3
  def render_template(view, template, layout_name, locals)
4
4
  if !view.respond_to?(:active_template_virtual_path) && template.respond_to?(:virtual_path)
5
5
  view.instance_eval <<~RUBY, __FILE__, __LINE__ + 1
6
- def active_template_virtual_path; "#{template.virtual_path}";end
6
+ def active_template_virtual_path; @_active_template_virtual_path || "#{template.virtual_path}";end
7
7
  RUBY
8
8
  end
9
9
 
@@ -11,6 +11,7 @@ module Props
11
11
  @builder = builder
12
12
  @traveled_path = []
13
13
  @partialer = Partialer.new(self, context, builder)
14
+ @fragment_name = nil
14
15
  end
15
16
 
16
17
  def deferred!
@@ -24,12 +25,20 @@ module Props
24
25
  def found!
25
26
  pass_opts = @found_options.clone || {}
26
27
  pass_opts.delete(:defer)
27
- traveled_path = @traveled_path[1..] || []
28
+ traveled_path = @traveled_path || []
28
29
  if !traveled_path.empty?
29
30
  pass_opts[:path_suffix] = traveled_path
30
31
  end
31
32
 
32
- [@found_block, pass_opts]
33
+ fragment_name = Fragment.fragment_name_from_options(pass_opts)
34
+ if fragment_name
35
+ @fragment_name = fragment_name
36
+ @fragment_path = @traveled_path.clone
37
+ end
38
+
39
+ fragment_context = @fragment_name
40
+
41
+ [@found_block, @traveled_path, pass_opts, @fragment_path, fragment_context]
33
42
  end
34
43
 
35
44
  def set_block_content!(*args)
@@ -50,6 +59,12 @@ module Props
50
59
 
51
60
  @depth += 1
52
61
  if options[:partial]
62
+ fragment_name = Fragment.fragment_name_from_options(options)
63
+ if fragment_name
64
+ @fragment_name = fragment_name
65
+ @fragment_path = @traveled_path.clone
66
+ end
67
+
53
68
  @partialer.handle(options)
54
69
  else
55
70
  yield
@@ -82,6 +97,17 @@ module Props
82
97
 
83
98
  if item
84
99
  pass_opts = @partialer.refine_options(options, item)
100
+
101
+ if (key = pass_opts[:key])
102
+ val = if item.respond_to? key
103
+ item.send(key)
104
+ elsif item.is_a? Hash
105
+ item[key] || item[key.to_sym]
106
+ end
107
+
108
+ pass_opts[:key] = [pass_opts[:key], val]
109
+ end
110
+
85
111
  @traveled_path.push(key_index)
86
112
 
87
113
  if @depth == @search_path.size - 1
@@ -94,6 +120,11 @@ module Props
94
120
 
95
121
  @depth += 1
96
122
  if pass_opts[:partial]
123
+ fragment_name = Fragment.fragment_name_from_options(pass_opts)
124
+ if fragment_name
125
+ @fragment_name = fragment_name
126
+ @fragment_path = @traveled_path.clone
127
+ end
97
128
  # todo: what happens when cached: true is passed?
98
129
  # would there be any problems with not using the collection_rende?
99
130
  @partialer.handle(pass_opts)
@@ -105,7 +136,7 @@ module Props
105
136
  end
106
137
  end
107
138
 
108
- def child!(options={}, &block)
139
+ def child!(options = {}, &block)
109
140
  return if @found_block
110
141
 
111
142
  child_index = @child_index || -1
@@ -128,7 +159,7 @@ module Props
128
159
  @depth -= 1
129
160
  end
130
161
 
131
- @child_index = child_index
162
+ @child_index = child_index
132
163
  end
133
164
  end
134
165
  end
@@ -1,3 +1,3 @@
1
1
  module Props
2
- VERSION = "1.0.0.alpha".freeze
2
+ VERSION = "1.0.0.alpha.3".freeze
3
3
  end
@@ -30,11 +30,14 @@ module Props
30
30
  :disable_deferments!,
31
31
  :set_block_content!,
32
32
  :traveled_path!,
33
+ :fragment_context!,
33
34
  to: :builder!
34
35
 
35
36
  def initialize(context = nil, options = {})
36
37
  @builder = BaseWithExtensions.new(self, context, options)
37
38
  @context = context
39
+ @fragment_context = nil
40
+ @found_path = []
38
41
  end
39
42
 
40
43
  def set!(key, options = {}, &block)
@@ -48,8 +51,11 @@ module Props
48
51
  options.delete(:dig)
49
52
 
50
53
  @builder.set!(key, options, &block)
51
- found_block, found_options = @builder.found!
54
+ found_block, found_path, found_options, fragment_path, fragment_context = @builder.found!
55
+ @found_path = found_path || []
56
+ @fragment_context = fragment_context
52
57
  @builder = prev_builder
58
+ @fragment_path = fragment_path
53
59
 
54
60
  if found_block
55
61
  set!(key, found_options, &found_block)
@@ -59,6 +65,18 @@ module Props
59
65
  end
60
66
  end
61
67
 
68
+ def partial!(**options)
69
+ @context.render options
70
+ end
71
+
72
+ def found_path!
73
+ @found_path[@fragment_path.size..].join(".")
74
+ end
75
+
76
+ def fragment_context!
77
+ @fragment_context
78
+ end
79
+
62
80
  def builder!
63
81
  @builder
64
82
  end
metadata CHANGED
@@ -1,13 +1,13 @@
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.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johny Ho
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-07-13 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: activesupport
@@ -106,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
106
  - !ruby/object:Gem::Version
107
107
  version: '0'
108
108
  requirements: []
109
- rubygems_version: 3.6.2
109
+ rubygems_version: 3.6.9
110
110
  specification_version: 4
111
111
  summary: A fast JSON builder
112
112
  test_files: []