bridgetown-core 0.19.1 → 0.21.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/bridgetown-core.gemspec +3 -4
  3. data/lib/bridgetown-core.rb +32 -16
  4. data/lib/bridgetown-core/cleaner.rb +7 -1
  5. data/lib/bridgetown-core/collection.rb +176 -77
  6. data/lib/bridgetown-core/commands/apply.rb +4 -3
  7. data/lib/bridgetown-core/commands/base.rb +9 -0
  8. data/lib/bridgetown-core/commands/build.rb +0 -11
  9. data/lib/bridgetown-core/commands/configure.rb +66 -0
  10. data/lib/bridgetown-core/commands/console.rb +4 -0
  11. data/lib/bridgetown-core/commands/doctor.rb +1 -19
  12. data/lib/bridgetown-core/commands/new.rb +8 -0
  13. data/lib/bridgetown-core/commands/plugins.rb +1 -0
  14. data/lib/bridgetown-core/commands/serve.rb +0 -14
  15. data/lib/bridgetown-core/component.rb +178 -0
  16. data/lib/bridgetown-core/concerns/data_accessible.rb +1 -0
  17. data/lib/bridgetown-core/concerns/front_matter_importer.rb +52 -0
  18. data/lib/bridgetown-core/concerns/site/configurable.rb +7 -3
  19. data/lib/bridgetown-core/concerns/site/content.rb +56 -15
  20. data/lib/bridgetown-core/concerns/site/processable.rb +1 -0
  21. data/lib/bridgetown-core/concerns/site/renderable.rb +26 -0
  22. data/lib/bridgetown-core/concerns/site/writable.rb +12 -2
  23. data/lib/bridgetown-core/concerns/validatable.rb +1 -4
  24. data/lib/bridgetown-core/configuration.rb +50 -29
  25. data/lib/bridgetown-core/configurations/.keep +0 -0
  26. data/lib/bridgetown-core/configurations/bt-postcss.rb +26 -0
  27. data/lib/bridgetown-core/configurations/bt-postcss/postcss.config.js +21 -0
  28. data/lib/bridgetown-core/configurations/minitesting.rb +95 -0
  29. data/lib/bridgetown-core/configurations/netlify.rb +6 -0
  30. data/lib/bridgetown-core/configurations/netlify/netlify.sh +14 -0
  31. data/lib/bridgetown-core/configurations/netlify/netlify.toml +44 -0
  32. data/lib/bridgetown-core/configurations/purgecss.rb +49 -0
  33. data/lib/bridgetown-core/configurations/stimulus.rb +49 -0
  34. data/lib/bridgetown-core/configurations/swup.rb +37 -0
  35. data/lib/bridgetown-core/configurations/tailwindcss.rb +29 -0
  36. data/lib/bridgetown-core/configurations/tailwindcss/css_imports.css +4 -0
  37. data/lib/bridgetown-core/configurations/tailwindcss/postcss.config.js +12 -0
  38. data/lib/bridgetown-core/configurations/turbo.rb +16 -0
  39. data/lib/bridgetown-core/converter.rb +23 -0
  40. data/lib/bridgetown-core/converters/erb_templates.rb +50 -41
  41. data/lib/bridgetown-core/converters/identity.rb +0 -9
  42. data/lib/bridgetown-core/converters/markdown.rb +14 -4
  43. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +5 -38
  44. data/lib/bridgetown-core/converters/ruby_templates.rb +17 -0
  45. data/lib/bridgetown-core/converters/smartypants.rb +3 -1
  46. data/lib/bridgetown-core/current.rb +10 -0
  47. data/lib/bridgetown-core/document.rb +7 -14
  48. data/lib/bridgetown-core/drops/collection_drop.rb +1 -1
  49. data/lib/bridgetown-core/drops/page_drop.rb +4 -0
  50. data/lib/bridgetown-core/drops/relations_drop.rb +23 -0
  51. data/lib/bridgetown-core/drops/resource_drop.rb +83 -0
  52. data/lib/bridgetown-core/drops/site_drop.rb +33 -8
  53. data/lib/bridgetown-core/drops/unified_payload_drop.rb +5 -0
  54. data/lib/bridgetown-core/entry_filter.rb +12 -25
  55. data/lib/bridgetown-core/errors.rb +0 -2
  56. data/lib/bridgetown-core/filters.rb +4 -27
  57. data/lib/bridgetown-core/filters/from_liquid.rb +23 -0
  58. data/lib/bridgetown-core/filters/url_filters.rb +12 -0
  59. data/lib/bridgetown-core/generator.rb +2 -1
  60. data/lib/bridgetown-core/generators/prototype_generator.rb +37 -19
  61. data/lib/bridgetown-core/helpers.rb +48 -9
  62. data/lib/bridgetown-core/layout.rb +28 -13
  63. data/lib/bridgetown-core/liquid_renderer/file.rb +1 -0
  64. data/lib/bridgetown-core/liquid_renderer/table.rb +1 -0
  65. data/lib/bridgetown-core/model/base.rb +138 -0
  66. data/lib/bridgetown-core/model/builder_origin.rb +40 -0
  67. data/lib/bridgetown-core/model/origin.rb +38 -0
  68. data/lib/bridgetown-core/model/repo_origin.rb +126 -0
  69. data/lib/bridgetown-core/page.rb +11 -2
  70. data/lib/bridgetown-core/plugin.rb +2 -26
  71. data/lib/bridgetown-core/plugin_manager.rb +1 -3
  72. data/lib/bridgetown-core/publisher.rb +7 -1
  73. data/lib/bridgetown-core/reader.rb +36 -21
  74. data/lib/bridgetown-core/readers/data_reader.rb +4 -4
  75. data/lib/bridgetown-core/readers/page_reader.rb +1 -0
  76. data/lib/bridgetown-core/readers/post_reader.rb +5 -4
  77. data/lib/bridgetown-core/regenerator.rb +8 -1
  78. data/lib/bridgetown-core/related_posts.rb +5 -5
  79. data/lib/bridgetown-core/renderer.rb +6 -13
  80. data/lib/bridgetown-core/resource/base.rb +317 -0
  81. data/lib/bridgetown-core/resource/destination.rb +49 -0
  82. data/lib/bridgetown-core/resource/permalink_processor.rb +179 -0
  83. data/lib/bridgetown-core/resource/relations.rb +132 -0
  84. data/lib/bridgetown-core/resource/taxonomy_term.rb +34 -0
  85. data/lib/bridgetown-core/resource/taxonomy_type.rb +56 -0
  86. data/lib/bridgetown-core/resource/transformer.rb +175 -0
  87. data/lib/bridgetown-core/ruby_template_view.rb +12 -4
  88. data/lib/bridgetown-core/site.rb +9 -1
  89. data/lib/bridgetown-core/static_file.rb +33 -10
  90. data/lib/bridgetown-core/tags/include.rb +1 -1
  91. data/lib/bridgetown-core/tags/post_url.rb +2 -2
  92. data/lib/bridgetown-core/url.rb +1 -0
  93. data/lib/bridgetown-core/utils.rb +49 -43
  94. data/lib/bridgetown-core/utils/require_gems.rb +60 -0
  95. data/lib/bridgetown-core/utils/ruby_exec.rb +6 -9
  96. data/lib/bridgetown-core/utils/ruby_front_matter.rb +39 -0
  97. data/lib/bridgetown-core/version.rb +2 -2
  98. data/lib/bridgetown-core/watcher.rb +1 -1
  99. data/lib/site_template/README.md +70 -0
  100. data/lib/site_template/package.json.erb +2 -2
  101. data/lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb +1 -1
  102. data/lib/site_template/webpack.config.js.erb +26 -6
  103. metadata +56 -44
  104. data/lib/bridgetown-core/external.rb +0 -58
  105. data/lib/bridgetown-core/page_without_a_file.rb +0 -17
  106. data/lib/bridgetown-core/path_manager.rb +0 -31
  107. data/lib/bridgetown-core/readers/collection_reader.rb +0 -23
  108. data/lib/bridgetown-core/readers/static_file_reader.rb +0 -25
  109. data/lib/bridgetown-core/utils/exec.rb +0 -26
  110. data/lib/bridgetown-core/utils/internet.rb +0 -37
  111. data/lib/bridgetown-core/utils/platforms.rb +0 -80
  112. data/lib/bridgetown-core/utils/thread_event.rb +0 -31
  113. data/lib/bridgetown-core/utils/win_tz.rb +0 -75
@@ -26,6 +26,7 @@ module Bridgetown
26
26
 
27
27
  def apply_automation
28
28
  @source_paths = [Dir.pwd]
29
+ @logger = Bridgetown.logger
29
30
 
30
31
  if options[:apply]
31
32
  apply_after_new_command
@@ -33,9 +34,9 @@ module Bridgetown
33
34
  apply_in_pwd
34
35
  end
35
36
  rescue SystemExit => e
36
- Bridgetown.logger.error "Problem occurred while running automation:"
37
+ @logger.error "Problem occurred while running automation:"
37
38
  e.backtrace[0..3].each do |backtrace_line|
38
- Bridgetown.logger.info backtrace_line if backtrace_line.include?(":in `apply'")
39
+ @logger.info backtrace_line if backtrace_line.include?(":in `apply'")
39
40
  end
40
41
  raise e
41
42
  end
@@ -66,7 +67,7 @@ module Bridgetown
66
67
  apply_from_url automation_command
67
68
  end
68
69
  rescue ArgumentError => e
69
- Bridgetown.logger.warn "Oops!", e.message
70
+ @logger.warn "Oops!", e.message
70
71
  end
71
72
  end
72
73
  end
@@ -25,6 +25,15 @@ module Bridgetown
25
25
  end
26
26
  end
27
27
 
28
+ desc "dream", "There's a place where that idea still exists as a reality"
29
+ def dream
30
+ puts ""
31
+ puts "🎶 The Dream of the 90s is Alive in Portland... ✨"
32
+ puts " https://youtu.be/U4hShMEk1Ew"
33
+ puts " https://youtu.be/0_HGqPGp9iY"
34
+ puts ""
35
+ end
36
+
28
37
  desc "help <command>", "Show detailed command usage information and exit"
29
38
  def help(subcommand = nil)
30
39
  if subcommand && respond_to?(subcommand)
@@ -79,17 +79,6 @@ module Bridgetown
79
79
  #
80
80
  # Returns nothing.
81
81
  def watch_site(config_options)
82
- # Warn Windows users that they might need to upgrade.
83
- if Utils::Platforms.bash_on_windows?
84
- Bridgetown.logger.warn "",
85
- "Auto-regeneration may not work on some Windows versions."
86
- Bridgetown.logger.warn "",
87
- "Please see: https://github.com/Microsoft/BashOnWindows/issues/216"
88
- Bridgetown.logger.warn "",
89
- "If it does not work, please upgrade Bash on Windows or "\
90
- "run Bridgetown with --no-watch."
91
- end
92
-
93
82
  Bridgetown::Watcher.watch(@site, config_options)
94
83
  end
95
84
 
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Commands
5
+ class Configure < Thor::Group
6
+ include Thor::Actions
7
+ extend Summarizable
8
+
9
+ Registrations.register do
10
+ register(Configure, "configure", "configure CONFIGURATION", Configure.summary)
11
+ end
12
+
13
+ def self.banner
14
+ "bridgetown configure CONFIGURATION(S)"
15
+ end
16
+ summary "Set up bundled Bridgetown configurations"
17
+
18
+ def self.exit_on_failure?
19
+ true
20
+ end
21
+
22
+ def perform_configurations
23
+ logger = Bridgetown.logger
24
+ list_configurations if args.empty?
25
+
26
+ args.each do |configuration|
27
+ configure configuration
28
+ rescue Thor::Error
29
+ logger.error "Error:".red, "🚨 Configuration doesn't exist: #{configuration}"
30
+ end
31
+ end
32
+
33
+ def self.source_root
34
+ File.expand_path("../configurations", __dir__)
35
+ end
36
+
37
+ protected
38
+
39
+ def configure(configuration)
40
+ configuration_file = find_in_source_paths("#{configuration}.rb")
41
+
42
+ inside(New.created_site_dir || Dir.pwd) do
43
+ Apply.new.invoke(:apply_automation, [configuration_file])
44
+ end
45
+ end
46
+
47
+ def list_configurations
48
+ say "Please specify a valid packaged configuration from the below list:\n\n"
49
+ configurations.each do |configuration|
50
+ configuration = set_color configuration, :blue, :bold
51
+ say configuration
52
+ end
53
+ say "\n"
54
+
55
+ docs_url = "https://www.bridgetownrb.com/docs/bundled-configurations".yellow.bold
56
+ say "For more info, check out the docs at: #{docs_url}"
57
+ end
58
+
59
+ def configurations
60
+ inside self.class.source_root do
61
+ return Dir.glob("*.rb").map { |file| file.sub(".rb", "") }
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -28,6 +28,7 @@ module Bridgetown
28
28
 
29
29
  def console
30
30
  require "irb"
31
+ require "irb/ext/save-history"
31
32
  require "amazing_print" unless options[:"bypass-ap"]
32
33
 
33
34
  Bridgetown.logger.info "Starting:", "Bridgetown v#{Bridgetown::VERSION.magenta}" \
@@ -50,6 +51,7 @@ module Bridgetown
50
51
  IRB.setup(nil)
51
52
  workspace = IRB::WorkSpace.new
52
53
  irb = IRB::Irb.new(workspace)
54
+ IRB.conf[:IRB_RC]&.call(irb.context)
53
55
  IRB.conf[:MAIN_CONTEXT] = irb.context
54
56
  eval("site = $BRIDGETOWN_SITE", workspace.binding, __FILE__, __LINE__)
55
57
  Bridgetown.logger.info "Console:", "Now loaded as " + "site".cyan + " variable."
@@ -68,6 +70,8 @@ module Bridgetown
68
70
  end
69
71
  irb.eval_input
70
72
  end
73
+ ensure
74
+ IRB.conf[:AT_EXIT].each(&:call)
71
75
  end
72
76
  end
73
77
  end
@@ -33,7 +33,6 @@ module Bridgetown
33
33
 
34
34
  def healthy?(site)
35
35
  [
36
- fsnotify_buggy?(site),
37
36
  !conflicting_urls(site),
38
37
  !urls_only_differ_by_case(site),
39
38
  proper_site_url?(site),
@@ -59,7 +58,7 @@ module Bridgetown
59
58
  conflicting_urls = false
60
59
  urls = {}
61
60
  urls = collect_urls(urls, site.pages, site.dest)
62
- urls = collect_urls(urls, site.posts.docs, site.dest)
61
+ urls = collect_urls(urls, site.collections.posts.docs, site.dest)
63
62
  urls.each do |url, paths|
64
63
  next unless paths.size > 1
65
64
 
@@ -70,23 +69,6 @@ module Bridgetown
70
69
  conflicting_urls
71
70
  end
72
71
 
73
- def fsnotify_buggy?(_site)
74
- return true unless Utils::Platforms.osx?
75
-
76
- if Dir.pwd != `pwd`.strip
77
- Bridgetown.logger.error " " + <<-STR.strip.gsub(%r!\n\s+!, "\n ")
78
- We have detected that there might be trouble using fsevent on your
79
- operating system, you can read https://github.com/thibaudgg/rb-fsevent/wiki/no-fsevents-fired-(OSX-bug)
80
- for possible work arounds or you can work around it immediately
81
- with `--force-polling`.
82
- STR
83
-
84
- false
85
- end
86
-
87
- true
88
- end
89
-
90
72
  def urls_only_differ_by_case(site)
91
73
  urls_only_differ_by_case = false
92
74
  urls = case_insensitive_urls(site.pages + site.docs_to_write, site.dest)
@@ -19,6 +19,10 @@ module Bridgetown
19
19
  aliases: "-a",
20
20
  banner: "PATH|URL",
21
21
  desc: "Apply an automation after creating the site scaffold"
22
+ class_option :configure,
23
+ aliases: "-c",
24
+ banner: "CONFIGURATION(S)",
25
+ desc: "Comma separated list of bundled configurations to perform"
22
26
  class_option :force,
23
27
  type: :boolean,
24
28
  desc: "Force creation even if PATH already exists"
@@ -100,6 +104,7 @@ module Bridgetown
100
104
  # then automatically execute bundle install from within the new site dir
101
105
  # unless the user opts to skip 'bundle install'.
102
106
  # rubocop:todo Metrics/CyclomaticComplexity
107
+ # rubocop:disable Metrics/PerceivedComplexity
103
108
  def after_install(path, cli_path, options = {})
104
109
  git_init path
105
110
 
@@ -110,6 +115,7 @@ module Bridgetown
110
115
  yarn_install path unless options["skip-yarn"]
111
116
 
112
117
  invoke(Apply, [], options) if options[:apply]
118
+ invoke(Configure, options[:configure].split(","), {}) if options[:configure]
113
119
 
114
120
  logger = Bridgetown.logger
115
121
  yarn_start = "yarn start"
@@ -130,6 +136,7 @@ module Bridgetown
130
136
  logger.info "Yarn install skipped.".yellow if @skipped_yarn
131
137
  end
132
138
  # rubocop:enable Metrics/CyclomaticComplexity
139
+ # rubocop:enable Metrics/PerceivedComplexity
133
140
 
134
141
  def bundle_install(path)
135
142
  unless Bridgetown.environment == "test"
@@ -151,6 +158,7 @@ module Bridgetown
151
158
  unless Bridgetown.environment == "test"
152
159
  inside(path) do
153
160
  run "git init", abort_on_failure: true
161
+ run "if [[ -n $(git status | grep 'On branch master') ]]; then git checkout -b main; fi"
154
162
  end
155
163
  end
156
164
  rescue SystemExit
@@ -150,6 +150,7 @@ module Bridgetown
150
150
  inside name do # rubocop:todo Metrics/BlockLength
151
151
  run "rm -rf .git"
152
152
  run "git init"
153
+ run "if [[ -n $(git status | grep 'On branch master') ]]; then git checkout -b main; fi"
153
154
 
154
155
  run "mv bridgetown-sample-plugin.gemspec #{new_gemspec}"
155
156
  gsub_file new_gemspec, "https://github.com/bridgetownrb/bridgetown-sample-plugin", "https://github.com/username/#{name}"
@@ -13,10 +13,6 @@ module Bridgetown
13
13
 
14
14
  class_option :host, aliases: "-H", desc: "Host to bind to"
15
15
  class_option :port, aliases: "-P", desc: "Port to listen on"
16
- class_option :open_url,
17
- aliases: "-o",
18
- type: :boolean,
19
- desc: "Launch your site in a browser"
20
16
  class_option :detach,
21
17
  aliases: "-B",
22
18
  type: :boolean,
@@ -169,16 +165,6 @@ module Bridgetown
169
165
  )
170
166
  end
171
167
 
172
- def launch_browser(server, opts)
173
- address = server_address(server, opts)
174
- return system "start", address if Utils::Platforms.windows?
175
- return system "xdg-open", address if Utils::Platforms.linux?
176
- return system "open", address if Utils::Platforms.osx?
177
-
178
- Bridgetown.logger.error "Refusing to launch browser; " \
179
- "Platform launcher unknown."
180
- end
181
-
182
168
  # Keep in our area with a thread or detach the server as requested
183
169
  # by the user. This method determines what we do based on what you
184
170
  # ask us to do.
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ class Component
5
+ extend Forwardable
6
+
7
+ def_delegators :@view_context, :helpers, :liquid_render, :partial
8
+
9
+ # @return [Bridgetown::Site]
10
+ attr_reader :site # will be nil unless you explicitly set a `@site` ivar
11
+
12
+ # @return [Bridgetown::RubyTemplateView, Bridgetown::Component]
13
+ attr_reader :view_context
14
+
15
+ class << self
16
+ attr_accessor :source_location
17
+
18
+ def inherited(child)
19
+ # Code cribbed from ViewComponent by GitHub:
20
+ # Derive the source location of the component Ruby file from the call stack
21
+ child.source_location = caller_locations(1, 10).reject do |l|
22
+ l.label == "inherited"
23
+ end[0].absolute_path
24
+
25
+ super
26
+ end
27
+
28
+ # Return the appropriate template renderer for a given extension.
29
+ # TODO: make this extensible
30
+ #
31
+ # @param ext [String] erb, slim, etc.
32
+ def renderer_for_ext(ext, &block)
33
+ case ext
34
+ when "erb"
35
+ include ERBCapture
36
+ Tilt::ErubiTemplate.new(component_template_path,
37
+ outvar: "@_erbout",
38
+ bufval: "Bridgetown::OutputBuffer.new",
39
+ engine_class: Bridgetown::ERBEngine,
40
+ &block)
41
+ when "serb" # requires serbea
42
+ include Serbea::Helpers
43
+ Tilt::SerbeaTemplate.new(component_template_path, &block)
44
+ when "slim" # requires bridgetown-slim
45
+ Slim::Template.new(component_template_path, &block)
46
+ when "haml" # requires bridgetown-haml
47
+ Tilt::HamlTemplate.new(component_template_path, &block)
48
+ else
49
+ raise NameError
50
+ end
51
+ rescue NameError, LoadError
52
+ raise "No component rendering engine could be found for .#{ext} templates"
53
+ end
54
+
55
+ # Find the first matching template path based on source location and extension.
56
+ #
57
+ # @return [String]
58
+ def component_template_path
59
+ stripped_path = File.join(
60
+ File.dirname(source_location),
61
+ File.basename(source_location, ".*")
62
+ )
63
+ supported_template_extensions.each do |ext|
64
+ test_path = "#{stripped_path}.#{ext}"
65
+ return test_path if File.exist?(test_path)
66
+
67
+ test_path = "#{stripped_path}.html.#{ext}"
68
+ return test_path if File.exist?(test_path)
69
+ end
70
+
71
+ raise "No matching templates could be found in #{File.dirname(source_location)}"
72
+ end
73
+
74
+ # Read the template file.
75
+ #
76
+ # @return [String]
77
+ def component_template_content
78
+ File.read(component_template_path)
79
+ end
80
+
81
+ # A list of extensions supported by the renderer
82
+ # TODO: make this extensible
83
+ #
84
+ # @return [Array<String>]
85
+ def supported_template_extensions
86
+ %w(erb serb slim haml)
87
+ end
88
+ end
89
+
90
+ # If a content block was originally passed into via `render`, capture its output.
91
+ #
92
+ # @return [String] or nil
93
+ def content
94
+ @_content ||= begin
95
+ view_context.capture(self, &@_content_block) if @_content_block
96
+ end
97
+ end
98
+
99
+ # Provide a render helper for evaluation within the component context.
100
+ #
101
+ # @param item [Object] a component supporting `render_in` or a partial name
102
+ # @param options [Hash] passed to the `partial` helper if needed
103
+ # @return [String]
104
+ def render(item, options = {}, &block)
105
+ if item.respond_to?(:render_in)
106
+ result = ""
107
+ capture do # this ensures no leaky interactions between BT<=>VC blocks
108
+ result = item.render_in(self, &block)
109
+ end
110
+ result&.html_safe
111
+ else
112
+ partial(item, options, &block)&.html_safe
113
+ end
114
+ end
115
+
116
+ # This is where the magic happens. Render the component within a view context.
117
+ #
118
+ # @param view_context [Bridgetown::RubyTemplateView]
119
+ def render_in(view_context, &block)
120
+ @view_context = view_context
121
+ @_content_block = block
122
+
123
+ if render?
124
+ before_render
125
+ template
126
+ else
127
+ ""
128
+ end
129
+ rescue StandardError => e
130
+ Bridgetown.logger.error "Component error:",
131
+ "#{self.class} encountered an error while "\
132
+ "rendering `#{self.class.component_template_path}'"
133
+ raise e
134
+ end
135
+
136
+ # Subclasses can override this method to return a string from their own
137
+ # template handling.
138
+ def template
139
+ call || _renderer.render(self)
140
+ end
141
+
142
+ # Typically not used but here as a compatibility nod toward ViewComponent.
143
+ def call
144
+ nil
145
+ end
146
+
147
+ # Subclasses can override this method to perform tasks before a render.
148
+ def before_render; end
149
+
150
+ # Subclasses can override this method to determine if the component should
151
+ # be rendered based on initialized data or other logic.
152
+ def render?
153
+ true
154
+ end
155
+
156
+ def _renderer
157
+ # TODO: figure out a way to compile templates for increased performance
158
+ @_renderer ||= begin
159
+ ext = File.extname(self.class.component_template_path).delete_prefix(".")
160
+ self.class.renderer_for_ext(ext) { self.class.component_template_content }
161
+ end
162
+ end
163
+
164
+ # rubocop:disable Style/MissingRespondToMissing
165
+ ruby2_keywords def method_missing(method, *args, &block)
166
+ if helpers.respond_to?(method.to_sym)
167
+ helpers.send method.to_sym, *args, &block
168
+ else
169
+ super
170
+ end
171
+ end
172
+
173
+ def respond_to_missing?(method, include_private = false)
174
+ helpers.respond_to?(method.to_sym, include_private) || super
175
+ end
176
+ # rubocop:enable Style/MissingRespondToMissing
177
+ end
178
+ end