From d785e5fcef4e0ec9a2d58bab57b73c6caa8b8f09 Mon Sep 17 00:00:00 2001 From: Jonathan Mast Date: Sun, 26 Jan 2020 12:08:00 -0500 Subject: [PATCH] Add support for rendering with block instead of partial Add a `render` macro to the ComponentHelper, which takes a block that is used to render the component instead of using the partial. This is mainly useful for small components that will be rendered many times, the overhead of rendering the partial can be quite significant. --- .../frontend/components/no_template/no_template.js | 1 + .../frontend/components/no_template/no_template.scss | 2 ++ .../components/no_template/no_template_component.rb | 9 +++++++++ lib/komponent/component_helper.rb | 6 ++++++ lib/komponent/component_renderer.rb | 6 +++++- test/komponent/component_test.rb | 2 +- test/komponent/komponent_helper_test.rb | 7 +++++++ 7 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 fixtures/my_app/frontend/components/no_template/no_template.js create mode 100644 fixtures/my_app/frontend/components/no_template/no_template.scss create mode 100644 fixtures/my_app/frontend/components/no_template/no_template_component.rb diff --git a/fixtures/my_app/frontend/components/no_template/no_template.js b/fixtures/my_app/frontend/components/no_template/no_template.js new file mode 100644 index 0000000..36fc60f --- /dev/null +++ b/fixtures/my_app/frontend/components/no_template/no_template.js @@ -0,0 +1 @@ +import "./no_template.scss"; diff --git a/fixtures/my_app/frontend/components/no_template/no_template.scss b/fixtures/my_app/frontend/components/no_template/no_template.scss new file mode 100644 index 0000000..d035f78 --- /dev/null +++ b/fixtures/my_app/frontend/components/no_template/no_template.scss @@ -0,0 +1,2 @@ +.no-template { +} diff --git a/fixtures/my_app/frontend/components/no_template/no_template_component.rb b/fixtures/my_app/frontend/components/no_template/no_template_component.rb new file mode 100644 index 0000000..2e93b11 --- /dev/null +++ b/fixtures/my_app/frontend/components/no_template/no_template_component.rb @@ -0,0 +1,9 @@ +module NoTemplateComponent + extend ComponentHelper + + render do |block| + content_tag :div, class: "no-template #{@additional_class}" do + block.call + end + end +end diff --git a/lib/komponent/component_helper.rb b/lib/komponent/component_helper.rb index 6f5c476..2c8d387 100644 --- a/lib/komponent/component_helper.rb +++ b/lib/komponent/component_helper.rb @@ -10,4 +10,10 @@ def property(name, options = {}) def self.extended(component) component.properties = {} end + + def render(&block) + @render_block = block + end + + attr_reader :render_block end diff --git a/lib/komponent/component_renderer.rb b/lib/komponent/component_renderer.rb index f343ebf..56dc3d9 100644 --- a/lib/komponent/component_renderer.rb +++ b/lib/komponent/component_renderer.rb @@ -76,7 +76,11 @@ def _render(component, locals = {}, options = {}, &block) define_singleton_method(:block_given_to_component) { block } end - @context.render("components/#{component}/#{parts.join('_')}", &block) + if component_module.respond_to?(:render_block) && component_module.render_block + @context.instance_exec(block, &component_module.render_block) + else + @context.render("components/#{component}/#{parts.join('_')}", &block) + end end def resolved_component_path(component) diff --git a/test/komponent/component_test.rb b/test/komponent/component_test.rb index 7f42214..1df8881 100644 --- a/test/komponent/component_test.rb +++ b/test/komponent/component_test.rb @@ -7,7 +7,7 @@ def test_all_returns_components all = Komponent::Component.all assert all.is_a?(Hash) - assert_equal all.count, 13 + assert_equal all.count, 14 assert all["foo"].is_a?(Komponent::Component) end diff --git a/test/komponent/komponent_helper_test.rb b/test/komponent/komponent_helper_test.rb index bc3f4a9..dab97cb 100644 --- a/test/komponent/komponent_helper_test.rb +++ b/test/komponent/komponent_helper_test.rb @@ -88,6 +88,7 @@ def test_helper_lists_components 'genius_button', 'hello', 'namespaced/button', + 'no_template', 'partial/universe', 'partial/universe_button', 'ping', @@ -108,4 +109,10 @@ def test_helper_renders_with_doc }), component_with_doc('all', world: "🌎", sunglasses: "😎").chomp end + + def test_helper_renders_without_template + assert_equal \ + %(
🌎
), + component('no_template', additional_class: "classy") { "🌎" }.chomp + end end