Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render helper with block containing Arbre element. #64

Conversation

varyonic
Copy link
Contributor

@varyonic varyonic commented Mar 3, 2017

This PR fixes #46 following the first option suggested by Sean. It monkey-patches ActionView::Base#capture so that the output of Arbre elements is not lost inside a Rails helper block, and it modifies Arbre::Element#method_missing to capture the output of Rails helper calls into text_nodes.

# and https://github.com/rails/rails/pull/18024#commitcomment-8975180
value = value.to_s if value.is_a?(Arbre::Element)

if string = buffer.presence || value and string.is_a?(String)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use && instead of and.

@@ -1,3 +1,19 @@
class ActionView::Base

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing frozen string literal comment.
Use nested module/class definitions instead of compact style.

@Fivell
Copy link
Member

Fivell commented Mar 4, 2017

@varyonic , is it still WIP ?

within(Element.new) { s = helpers.send(name, *args, &block) }
s.is_a?(Element) ? s.to_s : s
end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra empty line detected at class body end.

# We do not want such elements added to self, so we push a dummy
# current_arbre_element.
def helper_capture(name, *args, &block)
s = ''

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

@@ -177,11 +177,21 @@ def method_missing(name, *args, &block)
elsif assigns && assigns.has_key?(name)
assigns[name]
elsif helpers.respond_to?(name)
helpers.send(name, *args, &block)
value = helper_capture(name, *args, &block)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Useless assignment to variable - value.

get "/test/render_page_with_helpers"
expect(response).to be_success
expect(body).to eq <<-EOS
<span>before h1 link</span>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use 2 spaces for indentation in a heredoc by using <<~ instead of <<-.

@varyonic varyonic force-pushed the 46_rails_tag_helper_with_block_in_arbre_template branch from 6fc0d29 to 3f467ab Compare September 21, 2017 19:21
get "/test/render_page_with_helpers"
expect(response).to be_success
expect(body).to eq <<~EOS
<span>before h1 link</span>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use 2 spaces for indentation in a heredoc by using <<~ instead of <<~.

@@ -1,3 +1,20 @@
# frozen_string_literal: true
ActionView::Base.class_eval do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add an empty line after magic comments.

@varyonic varyonic force-pushed the 46_rails_tag_helper_with_block_in_arbre_template branch 2 times, most recently from 6fc0d29 to c5840c0 Compare September 21, 2017 19:33
@varyonic varyonic changed the title [WIP] Render helper with block. Render helper with block. Sep 21, 2017
@varyonic varyonic changed the title Render helper with block. Render helper with block containing Arbre element. Sep 21, 2017
# Override to handle Arbre elements inside helper blocks.
# See https://github.com/rails/rails/issues/17661
# and https://github.com/rails/rails/pull/18024#commitcomment-8975180
value = value.to_s if value.is_a?(Arbre::Element)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied ActionView::Helpers::CaptureHelper.capture and added this line to convert Arbre::Element#to_s so the output is not lost.

@varyonic
Copy link
Contributor Author

I was overcomplicating things by trying to eliminate text_node. link_to works with text_node and now the arbre inside the link_to block is captured and displayed in the order expected.

@varyonic varyonic force-pushed the 46_rails_tag_helper_with_block_in_arbre_template branch from c5840c0 to 82fb896 Compare September 21, 2017 20:04
get "/test/render_page_with_helpers"
expect(response).to be_success
expect(body).to eq <<EOS
<span>before h1 link</span>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use 2 spaces for indentation in a heredoc by using <<~ instead of <<.

@varyonic varyonic force-pushed the 46_rails_tag_helper_with_block_in_arbre_template branch from 82fb896 to ed8db93 Compare September 21, 2017 20:10
@activeadmin activeadmin deleted a comment from houndci-bot Sep 21, 2017
@varyonic varyonic force-pushed the 46_rails_tag_helper_with_block_in_arbre_template branch from ed8db93 to fbb048e Compare September 21, 2017 21:00
Copy link
Contributor

@seanlinsley seanlinsley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me! 😄 Could you write a changelog entry? It might also be valuable to document how to use Rails helpers with Arbre as a new section in the README.

@@ -1,3 +1,21 @@
# frozen_string_literal: true

ActionView::Base.class_eval do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this should be moved to its own file, named something like lib/arbre/rails/capture.rb

@seanlinsley
Copy link
Contributor

One concern with the monkeypatch is that it doesn't call the original implementation, so another gem that overrode capture would be in contention with Arbre.

This might work as an alternative:

ActionView::Base.prepend Module.new {
  def capture(*args)
    super *args do
      value = yield *args
      value = value.to_s if value.is_a? Arbre::Element
      value
    end
  end
}

I'm not sure if with_output_buffer is needed; since this basically just wraps the block in another block, the original implementation's call to with_output_buffer should theoretically be enough.

@varyonic
Copy link
Contributor Author

I'm going to take this as approved and consider the suggestions for later.

@varyonic varyonic merged commit 465fc4a into activeadmin:master Feb 10, 2018
@varyonic varyonic deleted the 46_rails_tag_helper_with_block_in_arbre_template branch June 4, 2018 17:37
deivid-rodriguez added a commit that referenced this pull request Apr 11, 2019
…_block_in_arbre_template"

This reverts commit 465fc4a, reversing
changes made to a3349fb.

# Conflicts:
#	spec/rails/integration/rendering_spec.rb
#	spec/rails/templates/arbre/page_with_helpers.arb
joshleblanc added a commit to joshleblanc/ilex that referenced this pull request Apr 18, 2021
This change implements activeadmin/arbre#64 https://github.com/activeadmin/arbre/pull/64/files which was reverted.

The initial PR was reverted because you could potentially get duplicate renders in certain situations. The workaround I can see is to return nil from the block if this occurs. I think this is an acceptable workaround for this library.
@varyonic varyonic restored the 46_rails_tag_helper_with_block_in_arbre_template branch January 14, 2022 21:00
@varyonic varyonic deleted the 46_rails_tag_helper_with_block_in_arbre_template branch January 10, 2023 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

using link_to with block in arbre template
4 participants