amber_component 1.1.1 → 1.2.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 +4 -4
- data/CHANGELOG.md +33 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +11 -5
- data/README.md +6 -3
- data/lib/amber_component/assets.rb +9 -12
- data/lib/amber_component/base.rb +28 -3
- data/lib/amber_component/rendering.rb +107 -9
- data/lib/amber_component/template_handler.rb +8 -9
- data/lib/amber_component/version.rb +1 -1
- data/lib/amber_component/views.rb +26 -151
- data/lib/amber_component.rb +0 -1
- metadata +2 -3
- data/lib/amber_component/template_handler/erb.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0142826c9117720944d7c6f3ab6a8c56e551ed684c92e1d7ce4857ccbe2632c0'
|
4
|
+
data.tar.gz: 749a03720a2a3a6b7131ffc0e432af7dce37e11d4375052f6b051b799f9f66be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c06aa0648eb8767949de4b69ab288a1534333f0281095d757daf9564402c24c896bb94b78206d2b9219ddbccd61db1dc67281480ee8ac52abf541d8c17e18bc9
|
7
|
+
data.tar.gz: 196d879455fc376f6558048e801522a865753ece6aec2ecb6f0888a867707a43a04b629d87c2a2767800280482ec9d375cf56008e74bdbafd56d4b5ab5f8f2e5
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,37 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
-
## [
|
3
|
+
## [1.2.0] - 2023-01-25
|
4
|
+
|
5
|
+
### Breaking changes
|
6
|
+
|
7
|
+
- Inline view syntax has been changed from `view :[view_type] { '[content]' }` to `view '[content]', type: :[view_type]`
|
8
|
+
|
9
|
+
- Overriding the view template when rendering a component has been removed (eg. `ExampleComponent.call view: '<h1>Some overriden view</h1>'`)
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- ERB compiled template caching in production
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
|
17
|
+
- View rendering pipeline has been rewritten
|
18
|
+
|
19
|
+
### Fixed
|
20
|
+
|
21
|
+
- Nesting components has been fixed
|
22
|
+
|
23
|
+
## [1.1.1] - 2022-11-14
|
24
|
+
|
25
|
+
### Added
|
26
|
+
|
27
|
+
- Support for webpacker
|
28
|
+
|
29
|
+
## [1.1.0] - 2022-11-13
|
30
|
+
|
31
|
+
### Added
|
32
|
+
|
33
|
+
- StimulusJS controllers for components
|
34
|
+
|
35
|
+
## [1.0.0] - 2022-11-07
|
4
36
|
|
5
37
|
- Initial release
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
amber_component (1.
|
4
|
+
amber_component (1.2.0)
|
5
5
|
actionview (>= 6)
|
6
6
|
activemodel (>= 6)
|
7
7
|
activesupport (>= 6)
|
@@ -48,9 +48,15 @@ GEM
|
|
48
48
|
ffi (1.15.5)
|
49
49
|
git (1.11.0)
|
50
50
|
rchardet (~> 1.8)
|
51
|
-
haml (
|
52
|
-
temple (>= 0.8.
|
51
|
+
haml (6.1.1)
|
52
|
+
temple (>= 0.8.2)
|
53
|
+
thor
|
53
54
|
tilt
|
55
|
+
haml-rails (2.1.0)
|
56
|
+
actionpack (>= 5.1)
|
57
|
+
activesupport (>= 5.1)
|
58
|
+
haml (>= 4.0.6)
|
59
|
+
railties (>= 5.1)
|
54
60
|
i18n (1.12.0)
|
55
61
|
concurrent-ruby (~> 1.0)
|
56
62
|
jaro_winkler (1.5.4)
|
@@ -139,7 +145,7 @@ GEM
|
|
139
145
|
thor (~> 1.0)
|
140
146
|
tilt (~> 2.0)
|
141
147
|
yard (~> 0.9, >= 0.9.24)
|
142
|
-
temple (0.
|
148
|
+
temple (0.10.0)
|
143
149
|
thor (1.2.1)
|
144
150
|
tilt (2.0.11)
|
145
151
|
tzinfo (2.0.5)
|
@@ -159,7 +165,7 @@ DEPENDENCIES
|
|
159
165
|
bundler-audit
|
160
166
|
byebug
|
161
167
|
git
|
162
|
-
haml
|
168
|
+
haml-rails
|
163
169
|
minitest (~> 5.0)
|
164
170
|
railties
|
165
171
|
rake (~> 13.0)
|
data/README.md
CHANGED
@@ -337,7 +337,10 @@ custom HTML to a component.
|
|
337
337
|
|
338
338
|
This works similarly to React's `props.children`.
|
339
339
|
|
340
|
-
To render the passed nested content call `
|
340
|
+
To render the passed nested content call `children(&block)` somewhere inside the ERB template/view.
|
341
|
+
If you're using another template language like Haml,
|
342
|
+
you may need to use `children{yield}` instead. This difference
|
343
|
+
is due to how these templates are compiled.
|
341
344
|
|
342
345
|
```ruby
|
343
346
|
# app/components/modal_component.rb
|
@@ -358,7 +361,7 @@ end
|
|
358
361
|
|
359
362
|
<div class="modal_body">
|
360
363
|
<!-- nested content will be rendered here -->
|
361
|
-
<%=
|
364
|
+
<%= children(&block) %>
|
362
365
|
</div>
|
363
366
|
|
364
367
|
<div class="modal_footer">
|
@@ -389,7 +392,7 @@ Note that this will raise an error when no block/nested content is provided.
|
|
389
392
|
|
390
393
|
In order to render nested content
|
391
394
|
only when it is present (will work without nested content)
|
392
|
-
you can use `yield
|
395
|
+
you can use `children(&block) if block_given?` in ERB templates (or `children{yield} if block_given?` for Haml and others)
|
393
396
|
|
394
397
|
In general `block_given?` will return `true` when a block/nested content is present, otherwise `false`.
|
395
398
|
You can use it to render content conditionally based on
|
@@ -5,15 +5,15 @@ module ::AmberComponent
|
|
5
5
|
module Assets
|
6
6
|
# Class methods for assets.
|
7
7
|
module ClassMethods
|
8
|
-
# @return [
|
8
|
+
# @return [Pathname]
|
9
9
|
def asset_dir_path
|
10
|
-
component_file_path
|
10
|
+
component_file_path = source_location.first
|
11
11
|
return asset_dir_from_name unless component_file_path
|
12
12
|
|
13
|
-
component_file_path.delete_suffix('.rb')
|
13
|
+
::Pathname.new component_file_path.delete_suffix('.rb')
|
14
14
|
end
|
15
15
|
|
16
|
-
# @return [
|
16
|
+
# @return [Pathname, nil]
|
17
17
|
def asset_dir_from_name
|
18
18
|
return unless defined?(::Rails)
|
19
19
|
|
@@ -23,17 +23,17 @@ module ::AmberComponent
|
|
23
23
|
# Get an array of all folders containing component assets.
|
24
24
|
# This method should only be used on the parent class `AmberComponent::Base` or `ApplicationComponent`.
|
25
25
|
#
|
26
|
-
# @return [Array<
|
26
|
+
# @return [Array<Pathname>]
|
27
27
|
def all_asset_dir_paths
|
28
28
|
subclasses.map(&:asset_dir_path)
|
29
29
|
end
|
30
30
|
|
31
|
-
# @param file_name [String, nil]
|
32
|
-
# @return [
|
31
|
+
# @param file_name [String, Pathname, nil]
|
32
|
+
# @return [Pathname, nil]
|
33
33
|
def asset_path(file_name)
|
34
34
|
return unless file_name
|
35
35
|
|
36
|
-
|
36
|
+
asset_dir_path / file_name
|
37
37
|
end
|
38
38
|
|
39
39
|
# Returns the name of the file inside the asset directory
|
@@ -45,15 +45,12 @@ module ::AmberComponent
|
|
45
45
|
return [] unless ::File.directory?(asset_dir_path)
|
46
46
|
|
47
47
|
::Dir.entries(asset_dir_path).select do |file|
|
48
|
-
next unless ::File.file?(
|
48
|
+
next unless ::File.file?(asset_dir_path / file)
|
49
49
|
|
50
50
|
file.match? type_regexp
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
# Instance methods for assets.
|
56
|
-
module InstanceMethods
|
57
|
-
end
|
58
55
|
end
|
59
56
|
end
|
data/lib/amber_component/base.rb
CHANGED
@@ -42,9 +42,7 @@ module ::AmberComponent
|
|
42
42
|
extend Helpers::ClassHelper
|
43
43
|
|
44
44
|
include Helpers::CssHelper
|
45
|
-
include Views::InstanceMethods
|
46
45
|
extend Views::ClassMethods
|
47
|
-
include Assets::InstanceMethods
|
48
46
|
extend Assets::ClassMethods
|
49
47
|
include Rendering::InstanceMethods
|
50
48
|
extend Rendering::ClassMethods
|
@@ -57,18 +55,40 @@ module ::AmberComponent
|
|
57
55
|
memoize :asset_dir_path
|
58
56
|
|
59
57
|
# Memoize these methods in production
|
60
|
-
if ::
|
58
|
+
if defined?(::Rails.env) && ::Rails.env.production?
|
61
59
|
memoize :view_path
|
62
60
|
memoize :view_file_name
|
63
61
|
memoize :view_type
|
64
62
|
end
|
65
63
|
|
64
|
+
# @return [Class]
|
65
|
+
def compiled_method_container
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
# @return [String]
|
70
|
+
def type
|
71
|
+
'text/html'
|
72
|
+
end
|
73
|
+
|
74
|
+
# @return [Symbol]
|
75
|
+
def format
|
76
|
+
:html
|
77
|
+
end
|
78
|
+
|
79
|
+
# @return [String]
|
80
|
+
def identifier
|
81
|
+
source_location.first
|
82
|
+
end
|
83
|
+
|
66
84
|
private
|
67
85
|
|
68
86
|
# @param subclass [Class]
|
69
87
|
# @return [void]
|
70
88
|
def inherited(subclass)
|
71
89
|
super
|
90
|
+
return unless subclass.name
|
91
|
+
|
72
92
|
method_body = lambda do |**kwargs, &block|
|
73
93
|
subclass.render(**kwargs, &block)
|
74
94
|
end
|
@@ -130,6 +150,11 @@ module ::AmberComponent
|
|
130
150
|
end
|
131
151
|
end
|
132
152
|
|
153
|
+
# @return [Class]
|
154
|
+
def compiled_method_container
|
155
|
+
self.class
|
156
|
+
end
|
157
|
+
|
133
158
|
private
|
134
159
|
|
135
160
|
# @param kwargs [Hash{Symbol => Object}]
|
@@ -3,17 +3,82 @@
|
|
3
3
|
module ::AmberComponent
|
4
4
|
# Provides universal methods for rendering components.
|
5
5
|
module Rendering
|
6
|
+
|
7
|
+
# @return [Symbol]
|
8
|
+
RENDER_TEMPLATE_METHOD_NAME = :__render
|
9
|
+
|
6
10
|
# Class methods for rendering.
|
7
11
|
module ClassMethods
|
8
12
|
# @param kwargs [Hash{Symbol => Object}]
|
9
13
|
# @return [String]
|
10
14
|
def render(**kwargs, &block)
|
11
|
-
|
12
|
-
|
13
|
-
comp.render(&block)
|
15
|
+
new(**kwargs).render(&block)
|
14
16
|
end
|
15
17
|
|
16
18
|
alias call render
|
19
|
+
|
20
|
+
# @return [Boolean]
|
21
|
+
def compiled?
|
22
|
+
method_defined?(RENDER_TEMPLATE_METHOD_NAME)
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Boolean]
|
26
|
+
def compile?
|
27
|
+
return true if defined?(::Rails.env) && ::Rails.env.development?
|
28
|
+
|
29
|
+
!compiled?
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param force [Boolean] force recompilation
|
33
|
+
# @return [void]
|
34
|
+
def compile(force: false)
|
35
|
+
return if !compile? && !force
|
36
|
+
return if template_handler.nil?
|
37
|
+
|
38
|
+
render_template_method_redefinition_lock.synchronize do
|
39
|
+
silence_redefinition_of_method(RENDER_TEMPLATE_METHOD_NAME)
|
40
|
+
# rubocop:disable Style/EvalWithLocation
|
41
|
+
class_eval <<~CODE, view_path.to_s, 0 # rubocop:disable Style/DocumentDynamicEvalDefinition
|
42
|
+
def #{RENDER_TEMPLATE_METHOD_NAME}(local_assigns, output_buffer, &block)
|
43
|
+
#{compiled_template_source}
|
44
|
+
end
|
45
|
+
CODE
|
46
|
+
# rubocop:enable Style/EvalWithLocation
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Class, nil]
|
51
|
+
def template_handler
|
52
|
+
@template_handler ||= ::ActionView::Template.registered_template_handler(view_type)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
# @return [Mutex]
|
58
|
+
def render_template_method_redefinition_lock
|
59
|
+
@render_template_method_redefinition_lock ||= ::Mutex.new
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [String]
|
63
|
+
def compiled_template_source
|
64
|
+
handler = template_handler
|
65
|
+
unless handler
|
66
|
+
raise UnknownViewTypeError,
|
67
|
+
"view type `#{view_type.inspect}` is not known in #{self}, " \
|
68
|
+
"available types: #{::ActionView::Template.template_handler_extensions.inspect}"
|
69
|
+
end
|
70
|
+
|
71
|
+
if handler.method(:call).parameters.length > 1
|
72
|
+
handler.call(self, view_template_source)
|
73
|
+
else
|
74
|
+
handler.call(
|
75
|
+
source: view_template_source,
|
76
|
+
identifier: identifier,
|
77
|
+
type: type
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
17
82
|
end
|
18
83
|
|
19
84
|
# Instance methods for rendering.
|
@@ -21,10 +86,7 @@ module ::AmberComponent
|
|
21
86
|
# @return [String]
|
22
87
|
def render(&block)
|
23
88
|
run_callbacks :render do
|
24
|
-
|
25
|
-
# styles = inject_styles
|
26
|
-
# element += styles unless styles.nil?
|
27
|
-
element.html_safe
|
89
|
+
compile_and_render(&block)
|
28
90
|
end
|
29
91
|
end
|
30
92
|
|
@@ -39,13 +101,49 @@ module ::AmberComponent
|
|
39
101
|
render
|
40
102
|
end
|
41
103
|
|
42
|
-
|
104
|
+
# @param args [Array<Object>]
|
105
|
+
# @return [String]
|
106
|
+
def nested_content(*args, &block)
|
107
|
+
block_self = block.binding.receiver
|
108
|
+
return block_self.safe_capture(*args, &block) if block_self.respond_to?(:safe_capture)
|
109
|
+
|
110
|
+
safe_capture(*args, &block)
|
111
|
+
end
|
112
|
+
alias children nested_content
|
113
|
+
|
114
|
+
def safe_capture(*args)
|
115
|
+
value = nil
|
116
|
+
buffer = with_output_buffer { value = yield(*args) }
|
117
|
+
buffer.presence || value.html_safe
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
# @return [String]
|
123
|
+
def compile_and_render(&block)
|
124
|
+
self.class.compile
|
125
|
+
if self.class.compiled?
|
126
|
+
return _run(
|
127
|
+
RENDER_TEMPLATE_METHOD_NAME,
|
128
|
+
self.class.template_handler,
|
129
|
+
[],
|
130
|
+
::ActionView::OutputBuffer.new,
|
131
|
+
&block
|
132
|
+
)
|
133
|
+
end
|
134
|
+
|
135
|
+
render_non_rails_string(
|
136
|
+
self.class.view_template_source,
|
137
|
+
self.class.view_type,
|
138
|
+
block
|
139
|
+
)
|
140
|
+
end
|
43
141
|
|
44
142
|
# @param content [String]
|
45
143
|
# @param type [Symbol]
|
46
144
|
# @param block [Proc, nil]
|
47
145
|
# @return [String]
|
48
|
-
def
|
146
|
+
def render_non_rails_string(content, type, block = nil)
|
49
147
|
TemplateHandler.render_from_string(self, content, type, block)
|
50
148
|
end
|
51
149
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ::AmberComponent
|
4
4
|
# Provides code which handles rendering different
|
5
|
-
# template languages.
|
5
|
+
# template languages outside of Rails.
|
6
6
|
module TemplateHandler
|
7
7
|
class << self
|
8
8
|
# @param context [AmberComponent::Base]
|
@@ -11,16 +11,15 @@ module ::AmberComponent
|
|
11
11
|
# @param block [Proc, nil]
|
12
12
|
# @return [String]
|
13
13
|
def render_from_string(context, content, type, block = nil)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
tilt_handler = ::Tilt[type]
|
15
|
+
raise UnknownViewTypeError, <<~ERR.squish unless tilt_handler
|
16
|
+
Unknown view type for `#{context.class}`!
|
17
|
+
Check return value of param type in `view type: :[type]`
|
18
|
+
or the view file extension.
|
19
|
+
ERR
|
19
20
|
|
20
|
-
|
21
|
+
tilt_handler.new { content }.render(context, &block).html_safe
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
25
|
-
|
26
|
-
require_relative 'template_handler/erb'
|
@@ -1,14 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'pathname'
|
4
|
+
|
3
5
|
module ::AmberComponent
|
4
6
|
# Provides methods concerning view registering and rendering.
|
5
7
|
module Views
|
6
|
-
# View types with built-in embedded Ruby
|
7
|
-
#
|
8
|
-
# @return [Set<Symbol>]
|
9
|
-
VIEW_TYPES_WITH_RUBY = ::Set[:erb, :haml, :slim].freeze
|
10
|
-
# @return [Set<Symbol>]
|
11
|
-
ALLOWED_VIEW_TYPES = ::Set[:erb, :haml, :slim, :html].freeze
|
12
8
|
# @return [Regexp]
|
13
9
|
VIEW_FILE_REGEXP = /^view\./.freeze
|
14
10
|
|
@@ -18,28 +14,25 @@ module ::AmberComponent
|
|
18
14
|
#
|
19
15
|
# Usage:
|
20
16
|
#
|
21
|
-
# view
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
# ERB
|
27
|
-
# end
|
17
|
+
# view <<~ERB
|
18
|
+
# <h1>
|
19
|
+
# Hello <%= @name %>
|
20
|
+
# </h1>
|
21
|
+
# ERB
|
28
22
|
#
|
29
23
|
# or:
|
30
24
|
#
|
31
|
-
# view :haml
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
# HAML
|
37
|
-
# end
|
25
|
+
# view <<~HAML, type: :haml
|
26
|
+
# %h1
|
27
|
+
# Hello
|
28
|
+
# = @name
|
29
|
+
# HAML
|
38
30
|
#
|
31
|
+
# @param content [String, Proc]
|
39
32
|
# @param type [Symbol]
|
40
33
|
# @return [void]
|
41
|
-
def view(type
|
42
|
-
@method_view = TypedContent.new(type: type, content:
|
34
|
+
def view(content, type: :erb)
|
35
|
+
@method_view = TypedContent.new(type: type, content: content)
|
43
36
|
end
|
44
37
|
|
45
38
|
# ERB/Haml/Slim view registered through the `view` method.
|
@@ -48,6 +41,13 @@ module ::AmberComponent
|
|
48
41
|
attr_reader :method_view
|
49
42
|
|
50
43
|
# @return [String]
|
44
|
+
def view_template_source
|
45
|
+
return @method_view.to_s if @method_view
|
46
|
+
|
47
|
+
::File.read(view_path)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [String, nil]
|
51
51
|
def view_path
|
52
52
|
asset_path view_file_name
|
53
53
|
end
|
@@ -62,136 +62,11 @@ module ::AmberComponent
|
|
62
62
|
|
63
63
|
# @return [Symbol]
|
64
64
|
def view_type
|
65
|
-
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
# Instance methods for views.
|
70
|
-
module InstanceMethods
|
71
|
-
protected
|
72
|
-
|
73
|
-
# @return [String]
|
74
|
-
def render_view(&block)
|
75
|
-
view_from_file = render_view_from_file(&block)
|
76
|
-
view_from_method = render_class_method_view(&block)
|
77
|
-
view_from_inline = render_view_from_inline(&block)
|
78
|
-
|
79
|
-
view_content = view_from_file unless view_from_file.empty?
|
80
|
-
view_content = view_from_method unless view_from_method.empty?
|
81
|
-
view_content = view_from_inline unless view_from_inline.empty?
|
82
|
-
|
83
|
-
if view_content.nil? || view_content.empty?
|
84
|
-
raise ViewFileNotFoundError, "View for `#{self.class}` could not be found!"
|
85
|
-
end
|
86
|
-
|
87
|
-
view_content
|
88
|
-
end
|
89
|
-
|
90
|
-
# Helper method to render view from string or with other provided type.
|
91
|
-
#
|
92
|
-
# Usage:
|
93
|
-
#
|
94
|
-
# render_view_from_content('<h1>Hello World</h1>')
|
95
|
-
#
|
96
|
-
# or:
|
97
|
-
#
|
98
|
-
# render_view_from_content content: '**Hello World**', type: 'md'
|
99
|
-
#
|
100
|
-
# @param content [TypedContent, Hash{Symbol => String, Symbol, Proc}, String]
|
101
|
-
# @return [String, nil]
|
102
|
-
def render_view_from_content(content, &block)
|
103
|
-
return '' unless content
|
104
|
-
return content if content.is_a?(::String)
|
105
|
-
|
106
|
-
content = TypedContent.wrap(content)
|
107
|
-
type = content.type
|
108
|
-
content = content.to_s
|
109
|
-
|
110
|
-
if content.empty?
|
111
|
-
raise EmptyViewError, <<~ERR.squish
|
112
|
-
Custom view for `#{self.class}` from view method cannot be empty!
|
113
|
-
ERR
|
114
|
-
end
|
115
|
-
|
116
|
-
unless ALLOWED_VIEW_TYPES.include? type
|
117
|
-
raise UnknownViewTypeError, <<~ERR.squish
|
118
|
-
Unknown view type for `#{self.class}` from view method!
|
119
|
-
Check return value of param type in `view :[type] do`
|
120
|
-
ERR
|
121
|
-
end
|
122
|
-
|
123
|
-
unless VIEW_TYPES_WITH_RUBY.include? type
|
124
|
-
# first render the content with ERB if the
|
125
|
-
# type does not support embedding Ruby by default
|
126
|
-
content = render_string(content, :erb, block)
|
127
|
-
end
|
128
|
-
|
129
|
-
render_string(content, type, block)
|
130
|
-
end
|
131
|
-
|
132
|
-
# @return [String]
|
133
|
-
def render_view_from_file(&block)
|
134
|
-
view_path = self.class.view_path
|
135
|
-
return '' if view_path.nil? || !::File.file?(view_path)
|
136
|
-
|
137
|
-
content = ::File.read(view_path)
|
138
|
-
type = self.class.view_type
|
139
|
-
|
140
|
-
unless VIEW_TYPES_WITH_RUBY.include? type
|
141
|
-
content = render_string(content, :erb, block)
|
142
|
-
end
|
143
|
-
|
144
|
-
render_string(content, type, block)
|
145
|
-
end
|
146
|
-
|
147
|
-
# Method returning view from method in class file.
|
148
|
-
# Usage:
|
149
|
-
#
|
150
|
-
# view do
|
151
|
-
# <<~HTML
|
152
|
-
# <h1>
|
153
|
-
# Hello <%= @name %>
|
154
|
-
# </h1>
|
155
|
-
# HTML
|
156
|
-
# end
|
157
|
-
#
|
158
|
-
# or:
|
159
|
-
#
|
160
|
-
# view :haml do
|
161
|
-
# <<~HAML
|
162
|
-
# %h1
|
163
|
-
# Hello
|
164
|
-
# = @name
|
165
|
-
# HAML
|
166
|
-
# end
|
167
|
-
#
|
168
|
-
# @return [String]
|
169
|
-
def render_class_method_view(&block)
|
170
|
-
render_view_from_content(self.class.method_view, &block)
|
171
|
-
end
|
172
|
-
|
173
|
-
# Method returning view from params in view.
|
174
|
-
# Usage:
|
175
|
-
#
|
176
|
-
# <%= ExampleComponent data: data, view: "<h1>Hello #{@name}</h1>" %>
|
177
|
-
#
|
178
|
-
# or:
|
179
|
-
#
|
180
|
-
# <%= ExampleComponent data: data, view: { content: "<h1>Hello #{@name}</h1>", type: 'erb' } %>
|
181
|
-
#
|
182
|
-
# @return [String]
|
183
|
-
def render_view_from_inline(&block)
|
184
|
-
data = \
|
185
|
-
if @view.is_a? ::String
|
186
|
-
TypedContent.new(
|
187
|
-
type: :erb,
|
188
|
-
content: @view
|
189
|
-
)
|
190
|
-
else
|
191
|
-
@view
|
192
|
-
end
|
65
|
+
return @method_view.type if @method_view
|
66
|
+
raise ViewFileNotFoundError, "No view file for #{self}" unless view_file_name
|
193
67
|
|
194
|
-
|
68
|
+
view_file_path = ::Pathname.new view_file_name
|
69
|
+
view_file_path.extname.delete_prefix('.').to_sym
|
195
70
|
end
|
196
71
|
end
|
197
72
|
end
|
data/lib/amber_component.rb
CHANGED
@@ -12,7 +12,6 @@ module ::AmberComponent
|
|
12
12
|
class Error < ::StandardError; end
|
13
13
|
class MissingPropsError < Error; end
|
14
14
|
class IncorrectPropTypeError < Error; end
|
15
|
-
class ViewFileNotFoundError < Error; end
|
16
15
|
class InvalidTypeError < Error; end
|
17
16
|
|
18
17
|
class EmptyViewError < Error; end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amber_component
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ruby-Amber
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2023-01-25 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: actionview
|
@@ -123,7 +123,6 @@ files:
|
|
123
123
|
- lib/amber_component/railtie.rb
|
124
124
|
- lib/amber_component/rendering.rb
|
125
125
|
- lib/amber_component/template_handler.rb
|
126
|
-
- lib/amber_component/template_handler/erb.rb
|
127
126
|
- lib/amber_component/test_helper.rb
|
128
127
|
- lib/amber_component/typed_content.rb
|
129
128
|
- lib/amber_component/version.rb
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'action_view'
|
4
|
-
require 'ostruct'
|
5
|
-
|
6
|
-
module ::AmberComponent
|
7
|
-
module TemplateHandler
|
8
|
-
# Handles rendering ERB with Rails-like syntax
|
9
|
-
class ERB < ::ActionView::Template::Handlers::ERB::Erubi
|
10
|
-
def initialize(input, properties = {})
|
11
|
-
properties[:bufvar] ||= "@output_buffer"
|
12
|
-
properties[:preamble] = "#{properties[:bufvar]}=#{::ActionView::OutputBuffer}.new;"
|
13
|
-
super
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|