【问题标题】:Rails: Unable to nest content_tagRails:无法嵌套 content_tag
【发布时间】:2013-02-20 23:38:38
【问题描述】:

我编写了一个 Rails 助手来创建一个嵌套的 HTML 列表。但是,这不能正确渲染。请问我做错了什么?

助手

content_tag :ul do
  [1, 2].each do |x|
    content_tag(:li, x)
    content_tag :ul do
      ['a', 'b'].each do |y|
        content_tag(:li, y)
        content_tag :ul do
          ['i', 'ii'].each do |z|
            content_tag(:li, z)
          end
        end
      end
    end
  end
end

预期输出

<ul>
  <li>1</li>
  <ul>
    <li>a</li>
    <ul>
      <li>i</li>
      <li>ii</li>
    </ul>
    <li>b</li>
    <ul>
      <li>i</li>
      <li>ii</li>
    </ul>
  <li>2</li>
  <ul>
    <li>a</li>
    <ul>
      <li>i</li>
      <li>ii</li>
    </ul>
    <li>b</li>
    <ul>
      <li>i</li>
      <li>ii</li>
    </ul>
  </ul>
</ul>

实际输出

<ul></ul>

【问题讨论】:

  • each 没有返回正确的值;尝试将其替换为 map
  • 我刚刚用map试了一下,但是输出是一样的。

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2


【解决方案1】:

这是解决方案:

content_tag(:ul) do
  [1, 2].map do |x|
    content_tag(:li, x) <<
    content_tag(:ul) do
      ['a', 'b'].map do |y|
        content_tag(:li, y) <<
        content_tag(:ul) do
          ['i', 'ii'].map do |z|
            content_tag(:li, z)
          end.join('').html_safe
        end
      end.join('').html_safe
    end
  end.join('').html_safe
end

问题是你必须在每个 content_tag 块的末尾返回一个 HTML 安全字符串:

# returns <li>asd</li>
content_tag('li') { 'asd' }

# returns <ul><li>asd</li></ul>
content_tag('ul') { content_tag('li') { 'asd' } }

# returns [1, 2]
[1, 2].each{ |x| content_tag('li', x) }

# returns ["<li>1</li>", "<li>2</li>"]
[1, 2].map{ |x| content_tag('li', x) }

# returns "<li>1</li><li>2</li>" not marked as HTML safe, 
# because `join` generates a new string
[1, 2].map{ |x| content_tag('li', x) }.join('')

# returns "<li>1</li><li>2</li>" marked as HTML safe
[1, 2].map{ |x| content_tag('li', x) }.join('').html_safe

# returns "<ul><li>1</li><li>2</li></ul>"
content_tag('ul') do
  [1, 2].map{ |x| content_tag('li', x) }.join('').html_safe
end

# returns "<ul><li>1</li><li>2</li></ul>"
content_tag('ul') do
  content_tag('li') { 'asd' } # this is ignored, since it is not returned
  [1, 2].map{ |x| content_tag('li', x) }.join('').html_safe
end

# returns "<ul><li>asd</li><li>1</li><li>2</li></ul>"
content_tag('ul') do
  content_tag('li') { 'asd' } <<
    [1, 2].map{ |x| content_tag('li', x) }.join('').html_safe
end

【讨论】:

  • 产生错误:syntax error, unexpected tSYMBEG, expecting keyword_do or '{' or '(' content_tag :ul do
  • 感谢您不仅提供了解决方案,而且如此清楚地解释了为什么我的代码不起作用。
猜你喜欢
  • 2011-05-11
  • 2015-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多