Ruby on Rails content_tag 已弃用,但我无法使用标签复制其嵌套功能

Ruby on Rails content_tag is deprecated, but I can't replicate its nesting capabilities using tag

我正在处理的项目需要一些数据 table 的列标题在 table.

下方的脚注中为 referenced/defined

由于它是动态内容,将根据需要脚注的列标题的数量进行循环,因此我需要通过 models/helpers 处理其中的大部分内容。我已经能够复制我们的美国设计师想要使用 content_tag 的 html,但是 rubocop 抱怨内容标签的使用,并说我应该使用 tag。但是我根本无法使用 tag 方法嵌套 html 标签。

我要制作的 html 部分是这样的(需要多少脚注就会重复):

<li id="id" class="p-2">
  <dl class="m-0"><dt class="d-inline">Unusual term: </dt>
    <dd class="d-inline">Text with the definition of the term.<a href="#id-ref" aria-label="Back to content">↵</a></dd>
  </dl>
</li>

生成它的基于 content_tag 的代码是这样的:

content_tag(:li,
  content_tag(:dl, [
    content_tag(:dt, 'Unusual term: ', class: "d-inline"),
    content_tag(:dd, [
      'Text with the definition of the term.',
      content_tag(:a, '↵', href: '#id-ref', aria: { label: "Back to content" })
    ].join.html_safe, class: "d-inline")
  ].join.html_safe, class: "m-0"),
id: 'id',
class: "p-2")

当我切换到使用 tag 时,我遇到的问题是同时获取 <dt><dd> 标签, 它们都有内容,嵌套在 <dl> 标签内(还有 <a> 标签,它也有内容,嵌套在上述 <dd> 标签内)。 tag 方法似乎只输出最后一段嵌套内容并忽略它之前的任何其他内容。

这是我试过的标签嵌套方法:

tag.li id: 'id', class: 'p-2' do
  tag.dl class: 'm-0' do
    (tag.dt 'Unusual term: ', class: 'd-inline') +
      (tag.dd 'Text with the definition of the term.', class: 'd-inline' do
        (tag.a arrow, href: anchor, aria: { label: 'Back to content' })
      end)
  end
end

这是它给我的输出。

<li id="id" class="p-2">
  <dl class="m-0"><dt class="d-inline">Unusual term: </dt>
    <dd class="d-inline"><a href="#id-ref" aria-label="Back to content">↵</a></dd>
  </dl>
</li>

正如你所看到的,它很接近,但是它缺少 <dd> 标签的文本内容,它应该在 <a> 标签开始之前输出。

有人能帮忙吗?有没有办法在不丢失内容的情况下嵌套标签?或者我应该放弃并用实际写出的 html 代码编写部分...?

在我看来 content_tagtag 是 rails 6.1.3.1 的一部分。看起来只有被弃用的是 tag 帮助器的格式默认为 XHMTL 空标签而不是 HTML 5 类型的标签。有报告称 rubocop 的错误行为是 content_tag,而 tag 本应作为目标。

您可能会检查 content_tag 的参数是否有空标签,因为它的默认方式可能与以前不同。

我现在已经找到了一种方法来嵌套这些标记方法以实现所需的 html 输出,使用以下代码:

link = link_to ' ↵', '#id-ref', aria: { label: 'Back to content' }

tag.li(id: 'id', class: 'p-2') do
  tag.dl(class: 'm-0') do
    (tag.dt 'Unusual term: ', class: 'd-inline') +
      (tag.dd ('Text with the definition of the term.' + link).html_safe, class: 'd-inline')
  end
end

如果有人有替代解决方案,我很想听听,但我认为这暂时有用。

编辑以添加新的解决方案

感谢@max 建议使用 concat 让我摆脱 #html_safe 我现在有了一段代码,我的用户体验设计师和 rubocop 都会很满意!这是:

tag.li(id: 'id', class: 'p-2') do
  tag.dl(class: 'm-0') do
    tag.dt('Unusual term:', class: 'd-inline') + ' ' +
    tag.dd(class: 'd-inline') do
      concat 'Text with the definition of the term.'
      concat tag.a(' ↵', href: '#id-ref', aria: { label: 'Back to content' })
    end
  end
end

再次感谢大家对我的问题提出的意见。非常感谢。

tag.li(id: 'id', class: 'p-2') do
  tag.dl(class: 'm-0') do
    concat tag.dt('Unusual term: ', class: 'd-inline')
    concat tag.dd(class: 'd-inline') do
       concat 'Text with the definition of the term. '
       concat tag.a(arrow, href: anchor, aria: { label: 'Back to content' })
    end
  end
end

每个 content_tagtag 都有自己的字符串缓冲区 - 通过使用 concat 输出到该字符串缓冲区。这使您可以在块中输出多次,而无需处理字符串连接和 #html_safe。此字符串缓冲区是 content_tag/tag 的 return 值。

无论您使用 content_tag 还是 tag,这都非常有效。

参见: