ruby-on-rails 如何创建呈现多个标记的帮助器

k75qkfdt  于 12个月前  发布在  Ruby
关注(0)|答案(3)|浏览(139)

在Rails 7.1中,将下面的代码段移动到helper方法中的正确方法是什么?

<%= button_tag type: "submit", class: "a" do %>
  <span class="b">SAVE</span>
  <%= svg "check-circle-solid" %>
<% end %>

我试

module ApplicationHelper
  def svg(name)
    file = Rails.root.join("app", "assets", "images", "#{name}.svg")
    File.read(file).html_safe
  end

  def primary_button(text:, icon:)
    button_tag type: "a" do
      content_tag("span", text, class: "b")
      svg(icon)
    end
  end
end

但是span没有渲染。

kxxlusnw

kxxlusnw1#

button_tag只是content_tag周围的一个薄 Package 器,当使用块调用时,它使用capture创建一个包含标记内容的字符串缓冲区。
在ERB示例中,这是可行的,因为纯文本直接输出到缓冲区,<%= ... %> ERB标记也输出到缓冲区。这个缓冲区加上外部标记是content_tag的返回值。

<%= button_tag type: "submit", class: "a" do %>
  <span class="b">SAVE</span> <-- raw text
  <%= svg "check-circle-solid" %> <-- the result of the expression is output
<% end %>

然而,在普通的Ruby方法中,表达式的结果不会自动打印到缓冲区:

def primary_button(text:, icon:)
    button_tag type: "a" do
      content_tag("span", text, class: "b") # this does absolutely nothing
      svg(icon)
    end
  end

只输出块的返回值,这是最后一个表达式。
解决这个问题的一种方法是使用concat输出到字符串缓冲区:

module ApplicationHelper
  # ...
  def primary_button(text:, icon:)
    button_tag type: "a" do
      concat(content_tag("span", text, class: "b"))
      concat(svg(icon))
    end
  end
end

您可以使用the more modern syntax为标记助手进一步清理它:

module ApplicationHelper
  # ...
  def primary_button(text:, icon:)
    tag.a do
      concat(tag.span(text, class: "b"))
      concat(svg(icon))
    end
  end
end
toiithl6

toiithl62#

在Ruby中,块的最后一行是返回的,所以在您的示例中,button_tag块的返回值是svg(icon)行。
要让辅助对象渲染出这两个,你需要将它们合并:

def primary_button(text:, icon:)
  button_tag type: "a" do
    content_tag("span", text, class: "b") + svg(icon)
  end
end
7uzetpgm

7uzetpgm3#

正如Unixmonkey在Ruby中提到的,最后一行的结果是一个返回值
我建议使用safe_join。您可以通过此方法使用数组传递一些元素
另外,我认为tag助手在代码中比content_tag更具可读性

def primary_button(text:, icon:)
  button_tag type: "a" do
    safe_join([tag.span(text, class: "b"), svg(icon)])
  end
end

顺便说一句,有一个方便的inline_svg gem来处理SVG

相关问题